﻿using Liju.Common;
using Liju.Model;
using LiJu.Common;
using LiJu.Db;
using LiJu.Model.Model;
using LiJu.Product;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;

namespace LiJu
{
    public partial class Work : Form
    {
        string strUserName;
        string strGongHao;

        /// <summary>
        /// 当前电批任务号
        /// </summary>
        public long CurrentTaskId = 1;

        /// <summary>
        /// 当日生产产品数量
        /// </summary>
        private int nToDayProductNum = 0;

        /// <summary>
        /// 当日打螺丝数量
        /// </summary>
        private int nToDayLuoSitNum = 0;

        /// <summary>
        /// 套筒列表
        /// </summary>
        List<SleeveModel> listSleeveModel;

        /// <summary>
        /// 套筒启用数量 默认全启用=4
        /// </summary>
        int nTaoTongEnableNum = 4;

        /// <summary>
        /// 套筒启用状态 默认全启用 0未启用 1启用
        /// </summary>
        bool[] arrTaoTongEnable = { true, true, true, true };

        /// <summary>
        /// 套筒提示状态 灯闪烁 IO监控线程中套筒到位情况不切换灯状态
        /// </summary>
        bool isTaoTongTishi = false;

        /// <summary>
        /// 套筒归位检测状态
        /// </summary>
        bool isTaoTongCheckFinish = false;

        /// <summary>
        /// 螺丝仓12 废螺丝仓3 锁等信息 ID从1开始
        /// </summary>
        List<ScrewModel> listScrewModel;

        /// <summary>
        /// 螺丝库存报警数量
        /// </summary>
        int[] arrayLuoSiWaringNum = { 0, 0, 0 };

        /// <summary>
        /// 位移坐标允许误差 百分比的数字部分 实际使用时*0.01
        /// </summary>
        double dPositionOffset = 5.0;

        /// <summary>
        /// Z轴允许误差 百分比的数字部分 实际使用时*0.01
        /// </summary>
        double dPositionOffsetZ = 5.0;

        /// <summary>
        /// Z轴编码器精度0.0244mm
        /// </summary>
        double dAccuracyZ = 1;
        
        /// <summary>
        /// 当前机台所在工序号
        /// </summary>
        int nGongXuNo = 1;

        /// <summary>
        /// 当前处于计算螺丝下拧阶段 可记录Z最低位置 0不计 1统计 2已返回NG PASS
        /// </summary>
        int nCanFuGao = 0;

        /// <summary>
        /// 打完螺丝后最大编码器Z值
        /// </summary>
        double dLuoSiFinishZ = 0;

        /// <summary>
        /// 电批任务号 目标扭力
        /// </summary>
        float fTargetTorque = 0.0f;

        /// <summary>
        /// 电批任务号 目标角度
        /// </summary>
        float fTargetAngle = 0.0f;

        /// <summary>
        /// 电批任务号 速度
        /// </summary>
        float fSpeed = 0.0f;

        /// <summary>
        /// 是否显示坐标
        /// </summary>
        bool bIsShowPostion = false;

        /// <summary>
        /// 位移编码器坐标监控
        /// </summary>
        System.Timers.Timer timerPositionMonitor = new System.Timers.Timer();
        Thread threadPositionMonitor;

        /// <summary>
        /// 电批目标坐标
        /// </summary>
        List<double> listdPositionNeed;

        /// <summary>
        /// 点检状态 0非点检状态 1点检中 2取消点检
        /// </summary>
        int DianJianState = 0;

        /// <summary>
        /// IO控制器 16IN值
        /// </summary>
        bool[] arrayInValue;

        /// <summary>
        /// IO控制器 废螺丝丢进废螺丝仓监控
        /// </summary>
        System.Timers.Timer timerIOMonitor = new System.Timers.Timer();
        Thread threadIOMonitor;

        /// <summary>
        /// true 正常模式 false 测试模式
        /// </summary>
        bool bIsWorkModel = true;

        /// <summary>
        /// 作业进行中
        /// </summary>
        bool bIsWorking = false;

        /// <summary>
        /// 作业完二次扫码状态 0初始状态 1正常二次扫码 2二次扫码 扫不同码
        /// </summary>
        int nHaveScan2 = 0;

        /// <summary>
        /// 前后2次扫码一样 作业中 再次扫码 产品NG
        /// </summary>
        bool ScanCodeSame = false;

        /// <summary>
        /// 螺丝机1 2 是否报警
        /// </summary>
        bool bIsWarning = false;

        /// <summary>
        /// 是否可以重新送螺丝
        /// </summary>
        bool bCanReSongLuoSi = false;

        /// <summary>
        /// 三色灯启用状态 0禁用 1启用
        /// </summary>
        bool bLedEnable = true;

        /// <summary>
        /// 打螺丝Pass后是否禁用电批使能 0不禁用 1禁用
        /// </summary>
        bool bOKDianPiEnable = true;

        /// <summary>
        /// NG后 true 作业结束  false 工艺二次判定
        /// </summary>
        bool bNGIsFinisth = true;

        /// <summary>
        /// 电批作业位移超限忽略时间(ms)
        /// </summary>
        int nWeiYIChaoXianTime = 0;

        /// <summary>
        /// 产品作业NG时 IO监控关闭蜂鸣要忽略此情况 true NG false 未NG 
        /// </summary>
        bool bProudctNG = false;

        /// <summary>
        /// 第一次扫码SN
        /// </summary>
        string SN1 = string.Empty;

        /// <summary>
        /// 当前工序名称 
        /// </summary>
        string strGongXuName = string.Empty;

        NGJudgment formNGJudgment = new NGJudgment();//异常判定窗口

        DianJian formDianJian = new DianJian();//点检窗口

        SongDingJudge formSongDingJudge = new SongDingJudge();//重新送钉判定窗口

        ProductTaskRecord productTaskRecord;//当前产品生产记录

        /// <summary>
        /// 当前产品打螺丝记录
        /// </summary>
        DataTable dtLuoSiRecordList;

        /// <summary>
        /// 语音文件表
        /// </summary>
        DataTable dtSound = new DataTable();

        public Work()
        {
            InitializeComponent();
            // 加载时启用默认双缓冲并提供无闪烁的图形呈现：
            this.DoubleBuffered = true;//设置本窗体
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
            //this.ActiveControl = null;//去掉当前控件焦点
            //SetScanerState(true);
            
            btStopWork.Visible = false;
            //lbWorkNo.Text = lbNiuLi.Text = lbAngle.Text = lbSpeed.Text = lbTip.Text = "";
            lbTip.Text = "";
            lbTaoTongNo.Text = "套筒序号：";
            lbLuoSiType.Text = "螺丝型号：";

            bIsShowPostion = ConfigurationManager.AppSettings["IsShowPostion"] == "1" ? true : false;//是否显示坐标
            UnifiedObj.DeviceEnable[0] = ConfigurationManager.AppSettings["IsHaveWeiYi"] == "1" ? true : false;//是否启用位移编码器
            UnifiedObj.DeviceEnable[1] = ConfigurationManager.AppSettings["IsHaveDianPi"] == "1" ? true : false;//是否启用电批
            UnifiedObj.DeviceEnable[2] = ConfigurationManager.AppSettings["IsHaveIO"] == "1" ? true : false;//是否启用IO
            UnifiedObj.DeviceInit();
            
            //获取语音文件
            dtSound = Bll.GetSoundFileList();

            //设备通讯 
            DataTable dtComSet = Bll.GetComPortList();
            if (dtComSet.Rows.Count > 0)
            {
                if (UnifiedObj.DeviceEnable[1])//是否使用电批
                {
                    //if (LiJu.Common.Batch.ConnectionState != "连接成功")
                    //{
                    //    //电批IP 端口
                    //    LiJu.Common.Batch.ipaddress = dtComSet.Rows[1]["PortName"].ToString().Trim();
                    //    LiJu.Common.Batch.ipport = Convert.ToInt32(dtComSet.Rows[1]["BaudRate"]);
                    //    //连接 开始握手并订阅结果
                    //    LiJu.Common.Batch.TCPConnection();
                    //    LiJu.Common.Batch.SetPhasesSubscribe();
                    //    LiJu.Common.Batch.SetLastCurve();
                    //    if (LiJu.Common.Batch.ConnectionState == "连接成功")
                    //    {
                    //        UnifiedObj.DeviceConState[1] = 1;
                    //        //禁止使能
                    //        LiJu.Common.Batch.DisEnable();
                    //        DDKBatch.SaveCurveAction += AddDDKScrewCurve;
                    //        DDKBatch.ScrewResultAction += LoadScrewResult;
                    //    }
                    //    else
                    //    {
                    //        MessageBox.Show(LiJu.Common.Batch.ConnectionState);
                    //    }
                    //}
                    LiJu.Common.DDKBatch.Connection();
                    if (LiJu.Common.DDKBatch.ddkState == 0)//连接成功
                    {
                        UnifiedObj.DeviceConState[1] = 1;
                        DDKBatch.SaveCurveAction += AddDDKScrewCurve;
                        //重置电批结果
                        UnifiedObj.DianPiOKNGClear();

                        //List<ProductTaskRecord> listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList("010461A1ER82900199");
                        //List<double> listNiuLi = new List<double>();
                        //List<double> listAngle = new List<double>();
                        //List<bool> listOKorNG = new List<bool>();
                        //for (int j = 1; j < listProductTaskRecord.Count; j++)
                        //{
                        //    listNiuLi.Add(Convert.ToDouble(listProductTaskRecord[j].TaskPamaReal1));
                        //    listAngle.Add(Convert.ToDouble(listProductTaskRecord[j].TaskPamaReal2));
                        //    listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                        //}
                        //Liju.Common.MES.WorkStationPass("010461A1ER82900199", listNiuLi, listAngle, listOKorNG, true);

                        //int n = 0;
                    }
                }
            }

            //初始化参数 螺丝库存报警数量
            listScrewModel = ScrewDbHelper.GetScrewModelList();
            if (listScrewModel.Count > 2)
            {
                //arrayLuoSiWaringNum[0] = listScrewModel[0].CapacityWarnNum;
                //arrayLuoSiWaringNum[1] = listScrewModel[1].CapacityWarnNum;
                //arrayLuoSiWaringNum[2] = listScrewModel[2].CapacityWarnNum;
                //lbLuoSiCang3.Text = "有 " + listScrewModel[2].CapacityNow;
                lbLuoSiCang3.Text = " " ;
            }

            //今日产量
            nToDayProductNum = ProductRecordDbHelper.GetProductTodayYield();
            lbProductNum.Text = nToDayProductNum.ToString();
            //今日螺丝数
            //nToDayLuoSitNum = ProductTaskRecordDbHelper.GetProductTaskTodayYield();
            DataTable dt = ProductTaskRecordDbHelper.GetProductTaskTodayOKNG();
            if (dt.Rows.Count > 0)
            {
                //listScrewModel[0].CapacityNow = Convert.ToInt32(dt.Rows[0]["OK1"]);
                //listScrewModel[0].CapacityNGNum = Convert.ToInt32(dt.Rows[0]["NG1"]);
                //lbLuoSiCang1.Text = "OK " + listScrewModel[0].CapacityNow;
                //lbLuoSiBaoFei1.Text = "NG " + dt.Rows[0]["NG1"].ToString();

                //listScrewModel[1].CapacityNow = Convert.ToInt32(dt.Rows[0]["OK2"]);
                //listScrewModel[1].CapacityNGNum = Convert.ToInt32(dt.Rows[0]["NG2"]);
                //lbLuoSiCang2.Text = "OK " + dt.Rows[0]["OK2"].ToString();
                //lbLuoSiBaoFei2.Text = "NG " + dt.Rows[0]["NG2"].ToString();

                //lbLuoSiBaoFei3.Text = "NG " + dt.Rows[0]["AllNG"].ToString();

                //nToDayLuoSitNum = Convert.ToInt32(dt.Rows[0]["AllOK"])+ Convert.ToInt32(dt.Rows[0]["AllNG"]);
                //lbLuoSiNum.Text = nToDayLuoSitNum.ToString();

                lbLuoSiCang1.Text = " " ;
                lbLuoSiBaoFei1.Text = " " ;
                lbLuoSiCang2.Text = " " ;
                lbLuoSiBaoFei2.Text = " " ;
                lbLuoSiBaoFei3.Text = " " ;
            }


            //套筒
            listSleeveModel = Bll.GetAllSleeveModels();

            dt = BLL.Bll.GetSettingData();
            if (dt.Rows.Count > 0)
            {
                dPositionOffset = Convert.ToDouble(dt.Rows[0]["CoordinateDeviation"]);
                bOKDianPiEnable = Convert.ToBoolean(dt.Rows[0]["OKDianPiEnable"]);
                bNGIsFinisth = Convert.ToBoolean(dt.Rows[0]["NGIsFinisth"]);
                dAccuracyZ = Convert.ToDouble(dt.Rows[0]["AccuracyZ"]);
                bLedEnable = dt.Rows[0]["LedEnable"].ToString().Trim() == "1" ? true : false;
                dPositionOffsetZ = Convert.ToDouble(dt.Rows[0]["CoordinateDeviationZ"]);
                nGongXuNo = Convert.ToInt32(dt.Rows[0]["GongXuNo"]);
                nWeiYIChaoXianTime = Convert.ToInt32(dt.Rows[0]["WeiYIChaoXianTime"]);                
                UnifiedObj.TuiGanRunTime = Convert.ToInt32(dt.Rows[0]["TuiGanRunTime"]);
                //套筒默认4个全启用 修改实际启用状态
                string[] array = dt.Rows[0]["TaoTongStateList"].ToString().Trim().Split(',');
                if (array[0] == "0")
                {
                    nTaoTongEnableNum -= 1;
                    arrTaoTongEnable[0] = false;
                }
                if (array[1] == "0")
                {
                    nTaoTongEnableNum -= 1;
                    arrTaoTongEnable[1] = false;

                }
                if (array[2] == "0")
                {
                    nTaoTongEnableNum -= 1;
                    arrTaoTongEnable[2] = false;
                }
                if (array[3] == "0")
                {
                    nTaoTongEnableNum -= 1;
                    arrTaoTongEnable[3] = false;
                }

            }

            //初始化IO 重置out关
            if (UnifiedObj.DeviceEnable[2])
            {
                if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                {
                    for (int i = 0; i < 4; i++)//重置三色灯
                    {
                        UnifiedObj.SetLed(false, i);
                        Thread.Sleep(20);
                        //UnifiedObj.SetTaoTongTuiChu(true, i);//套筒推杆掉电能保持位置 无需重置
                        //Thread.Sleep(20);
                    }
                    SongLuoSiReset(1);//关送钉1
                    Thread.Sleep(50);
                    SongLuoSiReset(2);//关送钉2
                    Thread.Sleep(50);
                }
                else
                {
                    MessageBox.Show("IO控制器连接异常。");
                }
            }

            //产品图片螺丝不能拖动
            productImgControl1.AllowDragFlag = false;

            //位移坐标监控程序
            timerPositionMonitor.Interval = 20;
            timerPositionMonitor.Elapsed += new System.Timers.ElapsedEventHandler(timerPositionMonitor_Elapsed);
            timerPositionMonitor.AutoReset = true; //设置一直执行(true)

            //IO控制器监控程序
            timerIOMonitor.Interval = 10;
            timerIOMonitor.Elapsed += new System.Timers.ElapsedEventHandler(timerIOMonitor_Elapsed);
            timerIOMonitor.AutoReset = true; //设置一直执行(true)

        }

        #region 解决控件添加背景图后闪屏问题

        /// <summary>
        /// 防止闪屏
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                //if (this.IsXpOr2003 == true)
                //{
                //    cp.ExStyle |= 0x00080000;
                //    this.Opacity = 1;
                //}
                return cp;
            }
        }

        private Boolean IsXpOr2003
        {
            get
            {
                OperatingSystem os = Environment.OSVersion;
                Version vs = os.Version;
                if (os.Platform == PlatformID.Win32NT)
                    if ((vs.Major == 5) && (vs.Major != 0))
                        return true;
                    else
                        return false;
                else
                    return false;
            }
        }

        #endregion

        private void Work_Shown(object sender, EventArgs e)
        {
            strUserName = ConfigurationManager.AppSettings["UserName"];
            strGongHao = ConfigurationManager.AppSettings["UserID"];

            //非管理员 没权限 测试模式按钮隐藏
            var menuRole = PageDataDto.SystemMenuRoleInfo();
            //if (menuRole.Work_Test )//工作模式 测试模式
            //{
            //    btWorkTest.Visible = true;
            //}
            //else
            //{
            //    btWorkTest.Visible = false;
            //}
            if (menuRole.Work_DianJian)//点检
            {
                btDianJian.Visible = true;
            }
            else
            {
                btDianJian.Visible = false;
            }

            if (UnifiedObj.DeviceConState[0] == 1)
            {
                timerPositionMonitor.Start();
            }
            if (UnifiedObj.DeviceConState[2] == 1)
            {
                timerIOMonitor.Start();
            }
            tbSN.Focus();

            if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)//待机亮黄灯
            {
                UnifiedObj.SetLed(true, 1);//亮黄灯
                Thread.Sleep(20);
            }

            dtLuoSiRecordList = new DataTable();
            dtLuoSiRecordList.Columns.Add("RowNo", typeof(string));
            dtLuoSiRecordList.Columns.Add("Torque", typeof(string));
            dtLuoSiRecordList.Columns.Add("Angle", typeof(string));
            dtLuoSiRecordList.Columns.Add("Result", typeof(string));
            //不显示未绑定的列
            dgvList.Font = new Font("宋体", 15);
            dgvList.AutoGenerateColumns = false;
            //dgvList.BackgroundColor = System.Drawing.Color.Transparent;
        }

        /// <summary>
        /// 读取螺丝任务号参数 并显示到页面 目标扭力 目标角度 速度 
        /// </summary>
        /// <param name="nTaskNo">螺丝任务号</param>
        /// <param name="LuoSiNo">第几个螺丝</param>
        /// <param name="bIsYuNing">true 预拧 false非预拧</param>
        private void GetLuoSiParamNiuLiAngleSpeed(int nTaskNo,string LuoSiNo="" ,bool bIsYuNing=false)
        {
            #region 马头参数
            ////查当前螺丝参数 扭力 速度 角度 打螺丝可能有多个步骤 可能存在多个步骤有对应参数的情况 找多个步骤里最大的值
            //DataTable dtLuoSiPama = BLL.Bll.GetTaskWithStep(nTaskNo);
            //this.Invoke(new MethodInvoker(() =>
            //{
            //    for (int j = 0; j < dtLuoSiPama.Rows.Count; j++)
            //    {
            //        if (dtLuoSiPama.Rows[j]["TargetTorqueLength"] != null && !string.IsNullOrWhiteSpace(dtLuoSiPama.Rows[j]["TargetTorqueLength"].ToString()))
            //        {
            //            if (fTargetTorqueLength < Convert.ToSingle(dtLuoSiPama.Rows[j]["TargetTorqueLength"]))
            //            {
            //                fTargetTorqueLength = Convert.ToSingle(dtLuoSiPama.Rows[j]["TargetTorqueLength"]);
            //                lbNiuLi.Text = dtLuoSiPama.Rows[j]["TargetTorqueLength"].ToString().Trim();//目标扭力
            //            }
            //        }
            //        if (dtLuoSiPama.Rows[j]["Speed"] != null && !string.IsNullOrWhiteSpace(dtLuoSiPama.Rows[j]["Speed"].ToString()))
            //        {
            //            if (fSpeed < Convert.ToSingle(dtLuoSiPama.Rows[j]["Speed"]))
            //            {
            //                fSpeed = Convert.ToSingle(dtLuoSiPama.Rows[j]["Speed"]);
            //                lbSpeed.Text = dtLuoSiPama.Rows[j]["Speed"].ToString().Trim();//目标速度
            //            }
            //        }
            //        if (dtLuoSiPama.Rows[j]["TargetAngle"] != null && !string.IsNullOrWhiteSpace(dtLuoSiPama.Rows[j]["TargetAngle"].ToString()))
            //        {
            //            if (fTargetAngle < Convert.ToSingle(dtLuoSiPama.Rows[j]["TargetAngle"]))
            //            {
            //                fTargetAngle = Convert.ToSingle(dtLuoSiPama.Rows[j]["TargetAngle"]);
            //                lbAngle.Text = dtLuoSiPama.Rows[j]["TargetAngle"].ToString().Trim();//目标角度
            //            }
            //        }
            //    }
            //}));
            #endregion

            //查当前螺丝参数 扭力 速度 角度 打螺丝可能有多个步骤 可能存在多个步骤有对应参数的情况 找多个步骤里最大的值
            fSpeed = 0;
            fTargetAngle = 0;
            fTargetTorque = 0;

            List<DDKScrewParam> listDDKScrewParam = Bll.GetDDKParameter(nTaskNo);
            for (int j = 0; j < listDDKScrewParam.Count; j++)
            {
                if (listDDKScrewParam[j].targetTorque > 0)
                {
                    if (fTargetTorque < listDDKScrewParam[j].targetTorque)
                    {
                        fTargetTorque = (float)listDDKScrewParam[j].targetTorque;
                    }
                }
                if (listDDKScrewParam[j].startSpeed > 0)
                {
                    if (fSpeed < listDDKScrewParam[j].startSpeed)
                    {
                        fSpeed = (float)listDDKScrewParam[j].startSpeed;
                    }
                }
                if (listDDKScrewParam[j].targeAngle > 0)
                {
                    if (fTargetAngle < listDDKScrewParam[j].targeAngle)
                    {
                        fTargetAngle = (float)listDDKScrewParam[j].targeAngle;
                    }
                }
            }

            this.Invoke(new MethodInvoker(() =>
            {
                //lbNiuLi.Text = fSpeed.ToString();//目标扭力
                //lbAngle.Text = fTargetAngle.ToString().Trim();//目标角度
                //lbSpeed.Text = fTargetTorqueLength.ToString().Trim();//目标速度
            }));
            UnifiedObj.WriteLog(1, "目标扭力:" + fTargetTorque + " 目标角度:" + fTargetAngle + " 目标速度:" + fSpeed);
        }

        /// <summary>
        /// 收到条码后 作业流程控制
        /// </summary>
        /// <param name="strSN"></param>
        protected void DoWork(string strSN)
        {
            this.ActiveControl = null;//去掉当前控件焦点
            List<ProductTaskRecord> listProductTaskRecord = new List<ProductTaskRecord>();
            if (string.IsNullOrWhiteSpace(strSN))
            {
                tbSN.Focus();
                return;
            }
            else if (strSN.ToLower().StartsWith("lock"))//扫的是锁的二维码 开锁
            {
                ScrewLog screwLog = new ScrewLog();
                screwLog.ScrewID = Convert.ToInt16(strSN.ToLower().Replace("lock", ""));
                screwLog.LockIO = Convert.ToInt16(strSN.ToLower().Replace("lock", ""));

                switch (screwLog.LockIO)//
                {
                    case 1://螺丝仓1
                        screwLog.ChangeType = 1;
                        screwLog.ChangeNum = 0;
                        screwLog.ChangePreNum = Convert.ToInt32(lbLuoSiCang1.Text.Replace("OK", ""));
                        screwLog.ChangeLastNum = 0;
                        break;
                    case 2://螺丝仓2
                        screwLog.ChangeType = 1;
                        screwLog.ChangeNum = 0;
                        screwLog.ChangePreNum = Convert.ToInt32(lbLuoSiCang2.Text.Replace("OK", ""));
                        screwLog.ChangeLastNum = 0;
                        break;
                    case 3://废螺丝仓 废螺丝仓开门 废螺丝数量清0
                        screwLog.ChangeType = 2;
                        screwLog.ChangeNum = Convert.ToInt32(lbLuoSiCang3.Text.Replace("有", ""));
                        screwLog.ChangePreNum = screwLog.ChangeNum;
                        screwLog.ChangeLastNum = 0;
                        this.BeginInvoke(new MethodInvoker(() =>
                        {
                            listScrewModel[2].CapacityNGNum = listScrewModel[2].CapacityNow = 0;
                            lbLuoSiCang3.Text = "有 0";
                            lbLuoSiBaoFei3.Text = "NG " + listScrewModel[1].CapacityNGNum;
                        }));
                        //更新螺丝仓NG数量
                        ScrewDbHelper.ResetLuoSiCangNgNum();
                        break;
                }
                screwLog.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                //增加开锁记录
                ScrewLogDbHelper.ScrewLogAdd(screwLog);
                //开锁
                UnifiedObj.LockOpen(Convert.ToInt16(strSN.ToLower().Replace("lock", "")));
                return;
            }
            else if (bIsWorking)
            {
                #region 产品作业中 扫另一个产品条码 2个产品都NG 
                if (SN1 != strSN)
                {
                    string NGReMark = "条码<" + SN1 + ">拧紧轴工站未作业或未作业完成，已送检。作业中又扫另一产品条码<" + strSN + ">";
                    ProductRecordModel product1 = ProductRecordDbHelper.GetProductRecordInfo(SN1);
                    if (product1 == null)
                    {
                        product1 = new ProductRecordModel();
                        product1.ProductSN = SN1;
                    }
                    product1.State = 3;
                    product1.NGReMark = NGReMark;
                    ProductRecordDbHelper.ProductRecordUpdate(product1);

                    ProductRecordModel product2 = ProductRecordDbHelper.GetProductRecordInfo(strSN);
                    if (product2 == null)
                    {
                        product2 = new ProductRecordModel();
                        product2.ProductSN = strSN;
                    }
                    product2.State = 3;
                    product2.NGReMark = NGReMark;
                    ProductRecordDbHelper.ProductRecordUpdate(product2);
                    UnifiedObj.WriteLog(1, NGReMark + "\r\n");

                    if (Liju.Common.MES.IsUseMES)
                    {
                        //若作业中 有打螺丝数据写MES
                        List<string> listNiuLi = new List<string>();
                        List<string> listAngle = new List<string>();
                        List<bool> listOKorNG = new List<bool>();
                        listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(SN1);
                        if (listProductTaskRecord != null && listProductTaskRecord.Count > 0)
                        {
                            for (int j = 0; j < listProductTaskRecord.Count; j++)
                            {
                                if (listProductTaskRecord[j].TightenPrepare == 0)//非预拧才上传MES
                                {
                                    listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                    listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                    listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                                }
                            }
                        }
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            bProudctNG = true;
                            UnifiedObj.SetLed(true, 3);//蜂鸣
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(true, 0);//亮红灯
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(false, 2);//灭绿灯
                        }

                        Liju.Common.MES.WorkStationNG(SN1, strGongXuName, Liju.Common.MES.WorkStation,
                            "NG原因：" + NGReMark, listNiuLi, listAngle, listOKorNG, false);

                        listNiuLi.Clear();
                        listAngle.Clear();
                        listOKorNG.Clear();
                        listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(strSN);
                        if (listProductTaskRecord != null && listProductTaskRecord.Count > 0)
                        {
                            for (int j = 0; j < listProductTaskRecord.Count; j++)
                            {
                                if (listProductTaskRecord[j].TightenPrepare == 0)//非预拧才上传MES
                                {
                                    listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                    listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                    listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                                }
                            }
                        }
                        Liju.Common.MES.WorkStationNG(strSN, strGongXuName, Liju.Common.MES.WorkStation, 
                            "NG原因：" + NGReMark, listNiuLi, listAngle, listOKorNG, false);
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            Thread.Sleep(300);
                            UnifiedObj.SetLed(false, 3);//关蜂鸣
                        }
                    }
                    BtStopWork_Click(null, null);
                    UpdateTip(NGReMark);
                    //PlaySound("作业中，请先完成当前产品，或停止作业后，再扫码。");
                }
                #endregion
                #region 产品作业中 重复扫码 NG
                else
                {
                    string NGReMark = "条码<" + SN1 + ">拧紧轴工站作业中，再次扫此产品条码，已送检。";
                    ProductRecordModel product1 = ProductRecordDbHelper.GetProductRecordInfo(SN1);
                    if (product1 == null)
                    {
                        product1 = new ProductRecordModel();
                        product1.ProductSN = SN1;
                    }
                    if (product1.State == 2)//产品作业中 重复扫码 NG
                    {
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            bProudctNG = true;
                            UnifiedObj.SetLed(true, 3);//蜂鸣
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(true, 0);//亮红灯
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(false, 2);//灭绿灯
                        }

                        product1.State = 3;
                        product1.NGReMark = NGReMark;
                        ProductRecordDbHelper.ProductRecordUpdate(product1);
                        UnifiedObj.WriteLog(1, NGReMark + "\r\n");

                        if (Liju.Common.MES.IsUseMES)
                        {
                            //若作业中 有打螺丝数据写MES
                            List<string> listNiuLi = new List<string>();
                            List<string> listAngle = new List<string>();
                            List<bool> listOKorNG = new List<bool>();
                            listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(SN1);
                            if (listProductTaskRecord != null && listProductTaskRecord.Count > 0)
                            {
                                for (int j = 0; j < listProductTaskRecord.Count; j++)
                                {
                                    if (listProductTaskRecord[j].TightenPrepare == 0)//非预拧才上传MES
                                    {
                                        listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                        listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                        listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                                    }
                                }
                            }
                            Liju.Common.MES.WorkStationNG(SN1, strGongXuName, Liju.Common.MES.WorkStation,
                                "NG原因：" + NGReMark, listNiuLi, listAngle, listOKorNG, false);
                        }
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            Thread.Sleep(300);
                            UnifiedObj.SetLed(false, 3);//关蜂鸣
                        }
                        BtStopWork_Click(null, null);
                        UpdateTip(NGReMark);
                        //PlaySound("作业中，再次扫此产品条码NG。");
                    }
                }
                #endregion
                return;
            }

            //检查设备状态

            bool bMesCheckPass = false;//NG返修后 重新扫码作业 MES检验通过 忽略本机NG记录 正常二次作业
            strGongXuName = "";//MES读SN得到工序名称
            if (Liju.Common.MES.IsUseMES)
            {
                MESRetrun oMESRetrun = new MESRetrun();
                oMESRetrun = Liju.Common.MES.GetWorkStationProduct(strSN);
                if (oMESRetrun.InterfaceJudgment)
                {
                    bMesCheckPass = true;
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lbProductName.Text = "产品名称：" + oMESRetrun.NJZ_data_list.MaterialName.Value.Trim();
                        lbOrder.Text = "订单号：" + oMESRetrun.NJZ_data_list.OrderNumber.Value.Trim();
                        lbWuLiaoCode.Text = "物料号：" + oMESRetrun.NJZ_data_list.MaterialNo.Value.Trim();
                        strGongXuName = oMESRetrun.NJZ_data_list.WorkingProcedure.Value.Trim();
                    }));
                }
                else
                {
                    ProductRecordModel product1 = ProductRecordDbHelper.GetProductRecordInfo(strSN);

                    strGongXuName = oMESRetrun.NJZ_data_list.WorkingProcedure.Value.Trim();//GYPDX-NLS04 当前应作业工序
                    string[] GongXu = strGongXuName.Split('-');//GYPDX-NLS04
                    string GongXuName = GongXu[GongXu.Length - 1];//NLS04
                    string GongXuNum = GongXuName.Substring(GongXuName.Length - 2, 2);//截取最后2位数字

                    string[] thisGongXu = Liju.Common.MES.WorkStation.Split('-');//GYPDX-DGL32-NLS03 当前工站信息
                    string thisGongXuName = thisGongXu[thisGongXu.Length - 1];//NLS03
                    string thisGongXuNum = thisGongXuName.Substring(thisGongXuName.Length - 2, 2);//截取最后2位数字
                    //作业完 再次扫码 提示是下一工序作业 则不锁 给提示即可
                    if ((product1 == null || (product1.State==1 || product1.State ==3)) && 
                        Convert.ToInt32(thisGongXuNum) + 1 == Convert.ToInt32(GongXuNum))
                    {
                        UpdateTip(oMESRetrun.ErrInfo);
                        return;
                    }
                    else if (product1 == null)//本工序未做过 无记录 跨工序作业 锁住产品
                    {
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            bProudctNG = true;
                            UnifiedObj.SetLed(true, 3);//蜂鸣
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(true, 0);//亮红灯
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(false, 2);//灭绿灯
                        }

                        product1 = new ProductRecordModel();
                        product1.ProductSN = strSN;
                        product1.State = 3;
                        product1.NGReMark = "非当前作业工序，需送品质确认：" + oMESRetrun.ErrInfo;
                        ProductRecordDbHelper.ProductRecordAdd(product1);
                        oMESRetrun = Liju.Common.MES.WorkStationNG(strSN, strGongXuName, "",
                            product1.NGReMark, null, null, null, false);

                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            Thread.Sleep(300);
                            UnifiedObj.SetLed(false, 3);//关蜂鸣
                        }

                        if (oMESRetrun.InterfaceJudgment)
                        {
                            BtStopWork_Click(null, null);
                            UpdateTip(oMESRetrun.ErrInfo + " 产品已锁定.");
                        }
                        else
                        {
                            UpdateTip(oMESRetrun.ErrInfo);
                        }
                        UnifiedObj.WriteLog(1, "SN:" + strSN + " " + product1.NGReMark + "\r\n");
                    }
                    else//本工序做过 有记录 再扫码 提示 不锁产品
                    {
                        //this.Invoke(new MethodInvoker(() =>
                        //{
                        //    tbSN.Text = "";
                        //}));
                        UpdateTip(oMESRetrun.ErrInfo);
                    }
                    return;
                }
            }
            //查产品 任务信息
            ProductModel productModel = ProductDbHelper.GetProductBySN(strSN);

            if (productModel == null)
            {
                UpdateTip("未查到此产品设置记录，请确认已添加此型号的产品信息。");
                PlaySound("未查到此产品设置记录，请确认已添加此型号的产品信息。");
                return;
            }
            if (!Liju.Common.MES.IsUseMES)
            {
                this.Invoke(new MethodInvoker(() =>
                {
                    lbProductName.Text = "产品名称：" + productModel.ProductName;
                }));
            }
            List<TaskModel> listTaskModel = TaskDbHelper.GetAllTaskByProductId(productModel.Id, nGongXuNo);
            if (listTaskModel.Count < 1)
            {
                UpdateTip("未查到此产品当前工序：" + nGongXuNo + "的任务记录，请确认已设置此型号产品当前工序的任务信息。");
                PlaySound("未查到此产品当前工序的任务记录，请确认已设置此型号产品当前工序的任务信息。");
                return;
            }
            List<ProductImgModel> listProductImgModel = ProductImgDbHelper.GetProductImgByProductIdGongXuNo(productModel.Id, nGongXuNo);
            if (listProductImgModel.Count < 1)
            {
                UpdateTip("未查到此产品的图片，请确认已添加此型号产品的图片信息。");
                PlaySound("未查到此产品的图片，请确认已添加此型号产品的图片信息。");
                return;
            }

            //初始化产品图片
            this.Invoke(new MethodInvoker(() =>
            {
                productImgControl1.ClearData();
                productImgControl1.InitProductImg(listProductImgModel, listTaskModel);
                productImgControl1.ChangeProductImgIndex(1);
            }));

            //查产品表 是否有记录 有记录 可能是上次做到一半未完成的 接着处理 无记录从头开始
            int nProductState = 0;//当前产品生产状态
            int nWorkNo = 1;//当前任务序号 第几个螺丝 从1开始
            int nTaskStepNo = 0;//当前任务步骤号 用于任务中断后面接着执行

            ProductRecordModel productRecord = ProductRecordDbHelper.GetProductRecordInfo(strSN);

            dtLuoSiRecordList.Clear();
            listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(strSN, true);
            if (productRecord != null && productRecord.State > 0)
            {
                nProductState = productRecord.State;
                nWorkNo = productRecord.WorkNo;
                nTaskStepNo = productRecord.TaskStepNo;
                for (int i = 0; i < listProductTaskRecord.Count; i++)
                {
                    DataRow row = dtLuoSiRecordList.NewRow();
                    row["Torque"] = listProductTaskRecord[i].TaskPamaReal1 ;
                    row["Angle"] = listProductTaskRecord[i].TaskPamaReal2 ;
                    if (listProductTaskRecord[i].TightenPrepare == 1)
                    {
                        row["Result"] = "预拧 ";
                        row["RowNo"] = (i + 1).ToString();
                    }
                    else
                    {
                        row["RowNo"] = listProductTaskRecord[i].WorkNo;
                    }
                    if (listProductTaskRecord[i].State == 1 || listProductTaskRecord[i].State == 4)
                    {
                        row["Result"] += "OK";
                    }
                    else if (listProductTaskRecord[i].State == 2 || listProductTaskRecord[i].State == 5)
                    {
                        row["Result"] += "NG";
                    }
                    dtLuoSiRecordList.Rows.Add(row);
                }

                switch (productRecord.State)//产品生产状态 0未开始 1PASS 2执行中 3NG
                {
                    case 1://1完成
                        UpdateTip("此产品 " + strSN + " 作业已完成。");
                        this.Invoke(new MethodInvoker(() =>
                        {
                            UpdateWorkStateShow(2);//通过
                            tbSN.Text = "";
                            tbSN.Focus();
                            dgvList.DataSource = null;
                            dgvList.DataSource = dtLuoSiRecordList;
                        }));
                        PlaySound("此产品所有任务已完成。");
                        //MessageBox.Show("此产品所有任务已完成。无需重复作业。");
                        return;
                    case 2://2执行中 接着上次步骤号执行
                        dgvList.BeginInvoke(new Action(() =>
                        {
                            dgvList.DataSource = null;
                            dgvList.DataSource = dtLuoSiRecordList;
                        }));
                        break;
                    case 3://3NG
                        if (bMesCheckPass)//NG返修后 重新扫码作业 MES检验通过 忽略本机NG记录 正常从头二次作业
                        {
                            nProductState = 0;
                            nWorkNo = 1;
                            nTaskStepNo = 0;
                            dtLuoSiRecordList.Clear();
                            dgvList.DataSource = null;
                            break;
                        }
                        else
                        { 
                            UpdateTip("<" + strSN + ">不合格，请送维修。");
                            this.Invoke(new MethodInvoker(() =>
                            {
                                UpdateWorkStateShow(3);//NG
                                tbSN.Text = "";
                                tbSN.Focus();
                                dgvList.DataSource = null;
                                dgvList.DataSource = dtLuoSiRecordList;
                            }));
                            PlaySound("当前产品不合格，请送维修。");
                            return;
                        }
                }
            }

            if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
            {
                //重置套筒绿灯 红灯
                for (int i = 1; i < 5; i++)
                {
                    UnifiedObj.SetTaoTongGreen(false, i);
                    Thread.Sleep(20);
                    UnifiedObj.SetTaoTongRed(false, i);
                    Thread.Sleep(20);
                }
            }
            SN1 = strSN;
            UnifiedObj.WriteLog(1, "SN:" + strSN);

            Int64 nReturn = 0;
            bIsWorking = true;

            //作业螺丝任务实体
            Int64 nProductTaskRecordID = 0;
            productTaskRecord = new ProductTaskRecord();
            //dtLuoSiRecordList.Clear();

            for (int i = nWorkNo; i < listTaskModel.Count + 1; i++)
            {
                if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)//打螺丝前关灯
                {
                    UnifiedObj.SetLed(true, 1);//亮黄灯
                    Thread.Sleep(20);
                    UnifiedObj.SetLed(false, 0);//灭红灯
                    Thread.Sleep(20);
                    UnifiedObj.SetLed(false, 2);//灭绿灯
                    Thread.Sleep(20);
                    UnifiedObj.SetLed(false, 3);//关蜂鸣
                }

                #region 当前螺丝设置的作业参数
                //当前套筒
                SleeveModel sleeveModelThis = listSleeveModel.Find(o => o.Id == listTaskModel[i - 1].SleeveModel);
                if (sleeveModelThis != null)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lbTaoTongNo.Text = "套筒序号：" + sleeveModelThis.Model.Trim();
                    }));
                }
                //当前螺丝
                double dScrewLength = 0;//螺丝长度
                ScrewModel screwModelThis = listScrewModel.Find(o => o.Id == listTaskModel[i - 1].ScrewModel);
                if (screwModelThis == null)//无需送螺丝
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lbLuoSiType.Text = "螺丝型号：";
                    }));
                }
                else
                {
                    dScrewLength = screwModelThis.ScrewLength;
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lbLuoSiType.Text = "螺丝型号：" + screwModelThis.Model.Trim();
                    }));
                }
                //当前任务号
                this.Invoke(new MethodInvoker(() =>
                {
                    btStopWork.Visible = true;
                    btDianJian.Visible = btTaoTongGuiWei.Visible = false;                    
                    lbTaskNo.Text = "电批任务号：" + listTaskModel[i - 1].ScrewDriverParam.ToString();
                    //lbWorkNo.Text = i + " / " + listTaskModel.Count;
                }));
                UnifiedObj.WriteLog(1, "第"+ i + "个螺丝 " + lbTaoTongNo.Text + " "+ 
                    lbLuoSiType.Text + " " + lbTaskNo.Text + " " + i + "/" + listTaskModel.Count);

                //查当前螺丝参数 扭力 速度 角度 打螺丝可能有多个步骤 可能存在多个步骤有对应参数的情况 找多个步骤里最大的值
                GetLuoSiParamNiuLiAngleSpeed(listTaskModel[i - 1].ScrewDriverParam);

                #endregion

                //电批目标坐标
                listdPositionNeed = listTaskModel[i - 1].ScrewLocation.Split(',').ToList().ConvertAll(s => Convert.ToDouble(s));
                
                if (UnifiedObj.DeviceEnable[1])//新螺丝重置电批结果
                {
                    UnifiedObj.DianPiOKNGClear();
                    Thread.Sleep(20);
                }

                switch (nTaskStepNo)//当前任务步骤号 用于任务中断后面接着执行
                {
                    case 0:
                        #region 准备打新的螺丝任务 取套筒 至 送螺丝指令发送完成

                        //初始化 禁用电批使能
                        if (UnifiedObj.DeviceConState[1] == 1 && bOKDianPiEnable)
                        {
                            //LiJu.Common.Batch.DisEnable();
                            //电批急停
                            UnifiedObj.SetDianPiCanWork(false);
                        }

                        this.Invoke(new MethodInvoker(() =>
                        {
                            UpdateWorkStateShow(1);//作业中
                            //加载产品图片 当前任务的螺钉图标 准备开始打螺丝
                            if (listTaskModel[i - 1].TightenPrepare == 0)
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart);
                            }
                            else
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart, 0);
                            }
                            bCanReSongLuoSi = btReSongDing.Visible = false;
                        }));
                        UnifiedObj.WriteLog(1, "0.1:准备打新的螺丝任务");

                        //检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
                        CheckAddOperateTaoTong(listTaskModel[i - 1].SleeveModel);

                        UnifiedObj.WriteLog(1, "0.2:取指定套筒完成");

                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }

                        //产品无生产记录 先添加主表记录
                        bool bIsAdd = true;//添加或更新 主表记录 
                        if (productRecord == null)
                        {
                            productRecord = new ProductRecordModel();
                            productRecord.ProductId = productModel.Id;
                            productRecord.ProductName = productModel.ProductName;
                            productRecord.ProductSN = strSN;

                            productRecord.TaskNum = listTaskModel.Count;
                            productRecord.ImgNum = productModel.ImgNum;
                            productRecord.OrderSN = "订单号";
                            productRecord.OrderNun = 1;
                            productRecord.Model = "产品型号";
                            if (listTaskModel[i - 1].ScrewModel > 0)
                            {
                                productRecord.TaskStepScrewNum = 1;//需送一个钉
                            }
                            else
                            {
                                productRecord.TaskStepScrewNum = 0;//无需送螺丝
                            }
                        }
                        else
                        {
                            bIsAdd = false;
                        }

                        //当前步骤螺丝ID>0需送螺丝 =0无需送螺丝    发送螺丝指令
                        bool bSongDing = false;
                        if (productRecord.TaskStepScrewNum > 0)
                        {
                            bSongDing = SongLuoSiSetOut(listTaskModel[i - 1].ScrewModel);
                            if (!bSongDing)//送钉失败 退出
                            {
                                UnifiedObj.WriteLog(1, "0.3:发 送螺丝指令 失败");
                                return;
                            }
                            UnifiedObj.WriteLog(1, "0.3.1:发 送螺丝指令 完成");
                        }
                        else
                        {
                            UnifiedObj.WriteLog(1, "0.3.2:无需送钉");
                        }

                        productRecord.State = 2;//产品生产状态 0未开始 1PASS 2执行中 3NG
                        productRecord.WorkNo = i;//第几个螺钉
                        productRecord.TaskStepNo = nTaskStepNo = 1; //下一步 监控螺丝送成功
                        productRecord.GongHao = strGongHao;
                        productRecord.UserName = strUserName;
                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }
                        if (bIsWorkModel)//工作模式才计产量
                        {
                            if (bIsAdd)
                            {
                                nReturn = ProductRecordDbHelper.ProductRecordAdd(productRecord);
                            }
                            else
                            {
                                nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                            }
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行760 AddProductRecord 添加产品记录异常。");
                                PlaySound("添加产品记录异常。");
                                bIsWorking = false;
                                return;
                            }
                            else if (bIsAdd)//返回添加记录ID
                            {
                                productRecord.ProductRecordID = nReturn;
                            }
                        }
                        //新增打第几个螺丝记录 用螺钉数量+1
                        productTaskRecord = new ProductTaskRecord();
                        productTaskRecord.ProductRecordID = productRecord.ProductRecordID;
                        productTaskRecord.ProductName = productModel.ProductName;
                        productTaskRecord.ProductSN = strSN;
                        productTaskRecord.TaskID = listTaskModel[i - 1].Id;
                        productTaskRecord.WorkNo = i;
                        productTaskRecord.TaskImgNo = listTaskModel[i - 1].ProductImgNum;
                        productTaskRecord.State = 3;//执行结果 0未执行 1 Pass 2 NG 3执行中
                        productTaskRecord.ScrewDriverParam = listTaskModel[i - 1].ScrewDriverParam;
                        productTaskRecord.ScrewLocation = listTaskModel[i - 1].ScrewControlLocation;
                        productTaskRecord.ScrewLocationReal = "";
                        productTaskRecord.SleeveModel = listTaskModel[i - 1].SleeveModel;
                        productTaskRecord.ScrewModel = listTaskModel[i - 1].ScrewModel;
                        productTaskRecord.ScrewNum = bSongDing ? 1 : 0;//新步骤会送钉 重做可能不送钉
                        productTaskRecord.TightenPrepare = listTaskModel[i - 1].TightenPrepare;
                        productTaskRecord.GongHao = strGongHao;
                        productTaskRecord.UserName = strUserName;
                        //读电批任务参数
                        productTaskRecord.TaskPama1 = fTargetTorque.ToString();//目标扭矩
                        productTaskRecord.TaskPama2 = fTargetAngle.ToString();//目标角度
                        productTaskRecord.TaskPama3 = fSpeed.ToString();//速度
                        productTaskRecord.TaskPamaReal1 = productTaskRecord.TaskPamaReal2 = productTaskRecord.TaskPamaReal3 = "";
                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }
                        if (bIsWorkModel)//工作模式才计产量
                        {
                            nReturn = ProductTaskRecordDbHelper.ProductTaskRecordAdd(productTaskRecord);
                            if (nReturn < 1)
                            {
                                nProductTaskRecordID = -1;
                                UpdateTip("Error:行800 AddProductTaskRecord 添加产品作业记录异常。");
                                PlaySound("添加产品作业记录异常。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                productTaskRecord.ProductTaskRecordID = nProductTaskRecordID = nReturn;
                            }
                        }
                        #endregion
                        //送钉指令发送完成 主表当前螺丝步骤号 TaskStepNo=nTaskStepNo 已更新为1
                        if (productRecord.TaskStepScrewNum > 0)
                        {
                            UnifiedObj.WriteLog(1, "0.4:已发送钉指令 0阶段完成");
                        }
                        else
                        {
                            UnifiedObj.WriteLog(1, "0.5:无需送钉 0阶段完成");
                        }
                        goto case 1;

                    case 1:
                        #region 实际送螺钉已完成
                        if (lbResult.Text != "作业中")
                        {
                            this.Invoke(new MethodInvoker(() =>
                            {
                                UpdateWorkStateShow(1);//作业中
                            }));
                        }
                        this.Invoke(new MethodInvoker(() =>
                        {
                            //加载产品图片 当前任务的螺钉图标 准备开始打螺丝
                            if (listTaskModel[i - 1].TightenPrepare == 0)
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart);
                            }
                            else
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart,0);
                            }
                            bCanReSongLuoSi = btReSongDing.Visible = true;
                        }));

                        if (bIsWorkModel && nProductTaskRecordID < 1)//异常等接着上次执行 没经过case 0 productTaskRecord 实体为空
                        {
                            productTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecord(productRecord.ProductRecordID,
                                listTaskModel[i - 1].Id, i, 3);
                            if (productTaskRecord == null)
                            {
                                UpdateTip("Error:行830 GetProductTaskRecord 未查询到产品作业记录。");
                                PlaySound("未查询到产品作业记录。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                nProductTaskRecordID = productTaskRecord.ProductTaskRecordID;
                            }
                        }

                        if (productRecord.TaskStepScrewNum > 0)//需要送钉才监控是否送成功
                        {
                            UpdateTip(listScrewModel[listTaskModel[i - 1].ScrewModel - 1].Model + " 送钉中...");
                            PlaySound("送丁中...");
                            SongLuoSiReset(listTaskModel[i - 1].ScrewModel);//重置送钉信号
                            UnifiedObj.WriteLog(1, "1.1:开始监控实际送钉是否成功.");
                            //监控实际送钉是否完成 更新页面螺丝库存 螺丝机ID 从1开始
                            SongLuoSiReal(listTaskModel[i - 1].ScrewModel);
                            UnifiedObj.WriteLog(1, "1.2:监控送钉结束");
                        }
                        else
                        {
                            UnifiedObj.WriteLog(1, "1.2.1:无需送钉 监控结束");
                        }
                        //检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
                        CheckAddOperateTaoTong(listTaskModel[i - 1].SleeveModel);
                        UnifiedObj.WriteLog(1, "1.3:取指定套筒完成");

                        productTaskRecord.State = 3;//执行结果 0已送钉未执行 1 Pass 2 NG 3执行中
                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }
                        if (bIsWorkModel)//工作模式才计产量
                        {
                            productRecord.TaskStepNo = nTaskStepNo = 2; //下一步到 等电批返回PASS NG 
                            productRecord.TaskStepScrewNum = 0;//当前步骤已打完螺丝 剩余待打螺丝=0 
                            nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行870 ProductRecordUpdate 送钉完成后，更新产品记录异常。");
                                PlaySound("送丁完成后|更新产品记录异常。");
                                bIsWorking = false;
                                return;
                            }

                            productTaskRecord.GongHao = strGongHao;
                            productTaskRecord.UserName = strUserName;
                            productTaskRecord.UpdateTime = DateTime.Now;
                            nReturn = ProductTaskRecordDbHelper.ProductTaskRecordUpdate(productTaskRecord);
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行880 ProductTaskRecordUpdate 送钉完成后，更新产品任务记录异常。");
                                PlaySound("送丁完成后|更新产品任务记录异常。");
                                bIsWorking = false;
                                return;
                            }
                        }
                        #endregion

                        //送钉完成 主表当前螺丝步骤号 TaskStepNo=nTaskStepNo 已更新为2
                        UnifiedObj.WriteLog(1, "1.4:送钉完成 1阶段完成");
                        goto case 2;

                    case 2:
                        #region 移动到位 电批发指令 电批可作业

                        if (lbResult.Text != "作业中")
                        {
                            this.Invoke(new MethodInvoker(() =>
                            {
                                UpdateWorkStateShow(1);//作业中
                            }));
                        }
                        this.Invoke(new MethodInvoker(() =>
                        {
                            //加载产品图片 当前任务的螺钉图标 准备开始打螺丝
                            if (listTaskModel[i - 1].TightenPrepare == 0)
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart);
                            }
                            else
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.ReadyStart, 0);
                            }
                            bCanReSongLuoSi = btReSongDing.Visible = true;
                        }));

                        if (bIsWorkModel && nProductTaskRecordID < 1)//异常等接着上次执行 没经过case 0 productTaskRecord 实体为空
                        {
                            productTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecord(productRecord.ProductRecordID,
                                listTaskModel[i - 1].Id, i, 3);
                            if (productTaskRecord == null)
                            {
                                UpdateTip("Error:行930 GetProductTaskRecord 未查询到产品作业记录。");
                                PlaySound("未查询到产品作业记录。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                nProductTaskRecordID = productTaskRecord.ProductTaskRecordID;
                            }
                        }
                        //电批开启吸附
                        if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                        {
                            UnifiedObj.SetDianPiXiFu(true);
                            Thread.Sleep(20);
                            UnifiedObj.WriteLog(1, "2.1:电批开启吸附");
                        }

                        //检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
                        CheckAddOperateTaoTong(listTaskModel[i - 1].SleeveModel);
                        UnifiedObj.WriteLog(1, "2.2:取指定套筒完成");

                        //UpdateTip("请将电批移动到：" + String.Join(",", listdPositionNeed));
                        UpdateTip("请将电批移动到图示" + i);
                        PlaySound("请将电批移动到图示位置。");

                        //监控电批移动指定位置
                        while (true)
                         {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }
                            if (UnifiedObj.DeviceConState[0] == 1)//有位移传感器 移动到指定位置误差范围内
                            {
                                if (Convert.ToDouble(UnifiedObj.arrayPosition[0]) >= listdPositionNeed[0] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[0]) <= listdPositionNeed[0] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) >= listdPositionNeed[1] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) <= listdPositionNeed[1] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) >= (listdPositionNeed[2] -
                                     (dScrewLength + listTaskModel[i - 1].ErrorLimit) / dAccuracyZ) * (1 - dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) <= (listdPositionNeed[2] +
                                     listTaskModel[i - 1].ErrorLimit / dAccuracyZ) * (1 + dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) >= listdPositionNeed[3] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) <= listdPositionNeed[3] * (1 + dPositionOffset * 0.01))
                                {
                                    this.Invoke(new MethodInvoker(() =>
                                    {
                                        lbPositionNow.Text = "电批当前位置：已到位,已到位,已到位,已到位";
                                    }));
                                    UpdateTip("电批已移动到指定位置。");
                                    PlaySound("电批已移动到指定位置。");
                                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)//移动到位黄变绿
                                    {
                                        UnifiedObj.SetLed(false, 1);//灭黄灯
                                        Thread.Sleep(20);
                                        UnifiedObj.SetLed(true, 2);//亮绿灯
                                        Thread.Sleep(20);
                                    }
                                    break;
                                }
                                else
                                {
                                    string str = string.Empty;
                                    if (Convert.ToDouble(UnifiedObj.arrayPosition[0]) < listdPositionNeed[0] * (1 - dPositionOffset * 0.01))
                                    {
                                        str = "请→,";
                                    }
                                    else if (Convert.ToDouble(UnifiedObj.arrayPosition[0]) > listdPositionNeed[0] * (1 + dPositionOffset * 0.01))
                                    {
                                        str = "请←,";
                                    }
                                    else
                                    {
                                        str = "已到位,";
                                    }

                                    if (Convert.ToDouble(UnifiedObj.arrayPosition[1]) < listdPositionNeed[1] * (1 - dPositionOffset * 0.01))
                                    {
                                        str += "请↑,";
                                    }
                                    else if (Convert.ToDouble(UnifiedObj.arrayPosition[1]) > listdPositionNeed[1] * (1 + dPositionOffset * 0.01))
                                    {
                                        str += "请↓,";
                                    }
                                    else
                                    {
                                        str += "已到位,";
                                    }

                                    if (Convert.ToDouble(UnifiedObj.arrayPosition[2]) < (listdPositionNeed[2] -
                                     (dScrewLength + listTaskModel[i - 1].ErrorLimit) / dAccuracyZ) * (1 - dPositionOffsetZ * 0.01))
                                    {
                                        str += "请下降,";
                                    }
                                    else if (Convert.ToDouble(UnifiedObj.arrayPosition[2]) > (listdPositionNeed[2] +
                                     listTaskModel[i - 1].ErrorLimit / dAccuracyZ) * (1 + dPositionOffsetZ * 0.01))
                                    {
                                        str += "请上升,";
                                    }
                                    else
                                    {
                                        str += "已到位,";
                                    }

                                    if (Convert.ToDouble(UnifiedObj.arrayPosition[3]) < listdPositionNeed[3] * (1 - dPositionOffset * 0.01))
                                    {
                                        str += "请↶";
                                    }
                                    else if (Convert.ToDouble(UnifiedObj.arrayPosition[3]) > listdPositionNeed[3] * (1 + dPositionOffset * 0.01))
                                    {
                                        str += "请↷";
                                    }
                                    else
                                    {
                                        str += "已到位";
                                    }
                                    this.Invoke(new MethodInvoker(() =>
                                    {
                                        lbPositionNow.Text = "电批当前位置：" + str;
                                    }));
                                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)//超出范围绿变黄
                                    {
                                        UnifiedObj.SetLed(false, 2);//灭绿灯
                                        Thread.Sleep(20);
                                        UnifiedObj.SetLed(true, 1);//亮黄灯
                                        Thread.Sleep(20);
                                    }

                                }
                                Thread.Sleep(100);
                            }
                            else//无位移编码器 模拟移动到位
                            {
                                UpdateTip("电批已移动到指定位置。");
                                PlaySound("电批已移动到指定位置。");
                                Thread.Sleep(2000);
                                break;
                            }
                        }
                        UnifiedObj.WriteLog(1, "2.3:电批移动到位");

                        //发IO指令 禁用电批正反转按钮功能 马头用发TCP指令模式 无法在用IO模式实现
                        if (UnifiedObj.DeviceEnable[1])
                        {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }
                            if (UnifiedObj.DeviceConState[1] == 1)
                            {
                                ////电批移动到位 发电批参数指令                        
                                //LiJu.Common.Batch.UseProgramIndex(listTaskModel[i - 1].ScrewDriverParam);
                                ////发电批使能
                                //LiJu.Common.Batch.Enable();

                                UnifiedObj.SetDDKTaskNo(listTaskModel[i - 1].ScrewDriverParam);

                                CurrentTaskId = listTaskModel[i - 1].Id;
                                UnifiedObj.WriteLog(1, "2.4:发电批参数指令");
                            }
                        }

                        //已发电批指令 更新任务状态 3执行中
                        if (bIsWorkModel && nProductTaskRecordID < 1)//异常等接着上次执行 没经过case 0 productTaskRecord 实体为空
                        {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }
                            productTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecord(productRecord.ProductRecordID,
                                listTaskModel[i - 1].Id, i, 3);
                            if (productTaskRecord == null)
                            {
                                UpdateTip("Error:行1000 GetProductTaskRecord 未查询到产品作业记录。");
                                PlaySound("未查询到产品作业记录。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                nProductTaskRecordID = productTaskRecord.ProductTaskRecordID;
                            }
                        }
                        productTaskRecord.State = 3;//执行结果 0已送钉未执行 1 Pass 2 NG 3执行中
                        productTaskRecord.GongHao = strGongHao;
                        productTaskRecord.UserName = strUserName;
                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }
                        if (bIsWorkModel)//工作模式才计产量
                        {
                            productTaskRecord.GongHao = strGongHao;
                            productTaskRecord.UserName = strUserName;
                            productTaskRecord.UpdateTime = DateTime.Now;
                            productRecord.TaskStepNo = nTaskStepNo = 3; //下一步到 等电批返回PASS NG 
                            nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行1020 ProductRecordUpdate 发电批指令后，更新产品记录异常。");
                                PlaySound("发电批指令后更新产品记录异常。");
                                bIsWorking = false;
                                return;
                            }

                            nReturn = ProductTaskRecordDbHelper.ProductTaskRecordUpdate(productTaskRecord);
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行1030 ProductTaskRecordUpdate 发电批指令后，更新产品任务记录异常。");
                                PlaySound("发电批指令后更新产品任务记录异常。");
                                bIsWorking = false;
                                return;
                            }
                        }
                        UnifiedObj.WriteLog(1, "2.5:已发电批指令 2阶段完成");
                        goto case 3;
                    #endregion
                    //移动到位 已发电批指令 主表当前螺丝步骤号 TaskStepNo=nTaskStepNo 已更新为3

                    case 3:
                        #region 电批作业 等电批返回结果 判断PASS NG 若移出指定范围 禁使能 返回 case 2重新定位

                        //加载产品图片 当前任务的螺钉图标 开始打螺丝
                        this.Invoke(new MethodInvoker(() =>
                        {
                            if (listTaskModel[i - 1].TightenPrepare == 0)
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Testing);
                            }
                            else
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Testing, 0);
                            }
                            //productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Testing);
                            bCanReSongLuoSi = btReSongDing.Visible = true;
                        }));

                        if (bIsWorkModel && nProductTaskRecordID < 1)//异常等接着上次执行 没经过case 0 productTaskRecord 实体为空
                        {
                            productTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecord(productRecord.ProductRecordID,
                                listTaskModel[i - 1].Id, i, 3);
                            if (productTaskRecord == null)
                            {
                                UpdateTip("Error:行1050 GetProductTaskRecord 未查询到产品作业记录。");
                                PlaySound("未查询到产品作业记录。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                nProductTaskRecordID = productTaskRecord.ProductTaskRecordID;
                            }
                        }
                        //电批开启吸附
                        if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                        {
                            UnifiedObj.SetDianPiXiFu(true);
                            Thread.Sleep(20);
                            UnifiedObj.WriteLog(1, "3.1:电批开启吸附");
                        }

                        //检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
                        CheckAddOperateTaoTong(listTaskModel[i - 1].SleeveModel);
                        UnifiedObj.WriteLog(1, "3.2:取指定套筒完成");

                        UpdateTip("请使用电批作业。");
                        PlaySound("请使用电批作业。");

                        UnifiedObj.DianPiCanWork = true;
                        UnifiedObj.SetDianPiCanWork(true);
                        Thread.Sleep(100);

                        DateTime dtDianPiWorkStart = DateTime.MinValue;//电批启动时间
                        //监控电批启动信号
                        while (true)
                        {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }

                            if (UnifiedObj.DeviceConState[0] == 1)//有位移传感器 移动到指定位置误差范围内
                            {
                                if (Convert.ToDouble(UnifiedObj.arrayPosition[0]) >= listdPositionNeed[0] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[0]) <= listdPositionNeed[0] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) >= listdPositionNeed[1] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) <= listdPositionNeed[1] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) >= (listdPositionNeed[2] -
                                     (dScrewLength + listTaskModel[i - 1].ErrorLimit) / dAccuracyZ) * (1 - dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) <= (listdPositionNeed[2] +
                                     listTaskModel[i - 1].ErrorLimit / dAccuracyZ) * (1 + dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) >= listdPositionNeed[3] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) <= listdPositionNeed[3] * (1 + dPositionOffset * 0.01))
                                {
                                    //电批在指定范围误差内 启动信号 发作业指令
                                    if (UnifiedObj.GetDianPiStart())
                                    {
                                        UnifiedObj.WriteLog(1, "3.3:电批启动键已按下");
                                        UnifiedObj.SetDianPiZhengZhuan(true);
                                        UnifiedObj.WriteLog(1, "3.4:电批开始作业");
                                        dtDianPiWorkStart = DateTime.Now;
                                        break;
                                    }
                                }
                                else//超出误差范围 禁用电批使能 跳到 case 2 重新移动到范围内
                                {
                                    //if (UnifiedObj.DeviceEnable[1])//有电批
                                    //{
                                    //    //LiJu.Common.Batch.DisEnable();
                                    //    //电批急停
                                    //    UnifiedObj.SetDianPiCanWork(false);
                                    //}
                                    nCanFuGao = 0;
                                    dLuoSiFinishZ = 0;
                                    goto case 2;
                                }
                            }
                            else//无位移传感器 算到位 电批开始作业
                            {
                                break;
                            }
                        }

                        bool bDianPiMoveOut = false;//电批作业过程中移出范围 停止作业
                        //监控电批作业完成
                        while (true)
                        {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }

                            if (UnifiedObj.DeviceConState[0] == 1)//有位移传感器 移动到指定位置误差范围内
                            {
                                if (Convert.ToDouble(UnifiedObj.arrayPosition[0]) >= listdPositionNeed[0] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[0]) <= listdPositionNeed[0] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) >= listdPositionNeed[1] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[1]) <= listdPositionNeed[1] * (1 + dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) >= (listdPositionNeed[2] -
                                     (dScrewLength + listTaskModel[i - 1].ErrorLimit) / dAccuracyZ) * (1 - dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[2]) <= (listdPositionNeed[2] +
                                     listTaskModel[i - 1].ErrorLimit / dAccuracyZ) * (1 + dPositionOffsetZ * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) >= listdPositionNeed[3] * (1 - dPositionOffset * 0.01) &&
                                    Convert.ToDouble(UnifiedObj.arrayPosition[3]) <= listdPositionNeed[3] * (1 + dPositionOffset * 0.01))
                                {

                                }
                                else//超出误差范围 禁用电批使能 跳到 case 2 重新移动到范围内
                                {
                                    //电批作业指定时间内 位移超出范围 忽略
                                    if ((DateTime.Now - dtDianPiWorkStart).TotalMilliseconds < nWeiYIChaoXianTime)
                                    {
                                        if (UnifiedObj.DeviceEnable[1] && UnifiedObj.GetDianPiOKNG()) //有电批结果
                                        {
                                            break;
                                        }
                                        Thread.Sleep(50);
                                        continue;
                                    }
                                    if (UnifiedObj.DeviceEnable[1])//有电批
                                    {
                                        //LiJu.Common.Batch.DisEnable();
                                        //电批急停
                                        UnifiedObj.SetDianPiCanWork(false);
                                        UpdateTip("电批作业中移出坐标范围，停止作业，产品NG。");
                                        UnifiedObj.WriteLog(1, "电批作业中移出坐标范围，停止作业，产品NG。");
                                    }
                                    nCanFuGao = 0;
                                    dLuoSiFinishZ = 0;
                                    bDianPiMoveOut = true;
                                    break;
                                    //goto case 2;
                                }
                            }
                            if (UnifiedObj.DeviceEnable[1]) //有电批
                            {
                                if (UnifiedObj.GetDianPiOKNG())
                                {
                                    break;
                                }
                            }
                            else//无电批
                            {
                                break;
                            }
                            Thread.Sleep(50);
                        }

                        //电批吸附关
                        if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                        {
                            UnifiedObj.SetDianPiXiFu(false);
                            Thread.Sleep(20);
                            UnifiedObj.WriteLog(1, "3.5:电批作业完 关吸附");
                        }

                        nCanFuGao = 1;
                        int nReturnState = 0;//电批返回结果 0无 1Pass 2NG

                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            bIsWorking = false;
                            return;
                        }

                        if (UnifiedObj.DeviceEnable[1])//有电批
                        {
                            #region 马头返回结果
                            //if (LiJu.Common.Batch.tightenModels.Count > 0)//等待电批返回结果
                            //{
                            //    if (LiJu.Common.Batch.tightenModels[0].TighteningStatus == "OK")
                            //    {
                            //        nReturnState = 1;
                            //        //禁用电批使能
                            //        if (bOKDianPiEnable)
                            //        {
                            //            LiJu.Common.Batch.DisEnable();
                            //        }
                            //    }
                            //    else
                            //    {
                            //        nReturnState = 2;
                            //    }

                            //    //读电批返回值 实际参数值 更新任务记录
                            //    productTaskRecord.TaskPamaReal1 = LiJu.Common.Batch.tightenModels[0].Torque;//实际扭力
                            //    productTaskRecord.TaskPamaReal2 = LiJu.Common.Batch.tightenModels[0].Angle;//实际角度

                            //    //更新页面信息
                            //    this.Invoke(new MethodInvoker(() =>
                            //    {
                            //        nCanFuGao = 2;//已返回电批结果 停止统计Z
                            //        bCanReSongLuoSi = btReSongDing.Visible = false;
                            //        lbNiuLi.Text = fTargetTorqueLength + "/" + productTaskRecord.TaskPamaReal1;//实际扭力
                            //        lbAngle.Text = fTargetAngle + "/" + productTaskRecord.TaskPamaReal2;//实际角度
                            //        lbSpeed.Text = fSpeed + "/" + Math.Round((dLuoSiFinishZ - listdPositionNeed[2]) * dAccuracyZ, 2) + "mm";//浮高
                            //    }));

                            //    UpdateTip("");

                            //    //读电批返回值 实际参数值 更新任务记录
                            //    productTaskRecord.TaskPamaReal1 = LiJu.Common.Batch.tightenModels[0].Torque;//实际扭力
                            //    productTaskRecord.TaskPamaReal2 = LiJu.Common.Batch.tightenModels[0].Angle;//实际角度

                            //    //更新页面信息
                            //    this.Invoke(new MethodInvoker(() =>
                            //    {
                            //        nCanFuGao = 2;//已返回电批结果 停止统计Z
                            //        bCanReSongLuoSi = btReSongDing.Visible = false;
                            //        lbNiuLi.Text = fTargetTorqueLength + "/" + productTaskRecord.TaskPamaReal1;//实际扭力
                            //        lbAngle.Text = fTargetAngle + "/" + productTaskRecord.TaskPamaReal2;//实际角度
                            //        lbSpeed.Text = fSpeed + "/" + Math.Round((dLuoSiFinishZ - listdPositionNeed[2]) * dAccuracyZ, 2) + "mm";//浮高
                            //    }));
                            //    break;
                            //}
                            #endregion

                            #region DDK返回结果
                            if (bDianPiMoveOut)
                            {
                                //电批作业过程中移出范围 停止作业 无实际扭力 角度
                                productTaskRecord.TaskPamaReal1 = "位置超限";//实际扭力
                                productTaskRecord.TaskPamaReal2 = "位置超限";//实际角度
                                nReturnState = 2;
                            }
                            else if (UnifiedObj.GetDianPiOKNG())//DDK作业完 可读取结果
                            {
                                UnifiedObj.DianPiCanWork = false;
                                //电批急停
                                UnifiedObj.SetDianPiCanWork(false);
                                Thread.Sleep(50);
                                    
                                ScrewResult screwResult = new ScrewResult();
                                screwResult = DDKBatch.ReadScrewResult();
                                if (screwResult.result == 0)//NG
                                {
                                    nReturnState = 2;
                                }
                                else if (screwResult.result == 1)//OK
                                {
                                    nReturnState = 1;
                                }
                                //重置电批结果
                                UnifiedObj.DianPiOKNGClear();
                                Thread.Sleep(50);

                                UpdateTip("");

                                //读电批返回值 实际参数值 更新任务记录
                                productTaskRecord.TaskPamaReal1 = screwResult.lastTorque.ToString();//实际扭力
                                productTaskRecord.TaskPamaReal2 = screwResult.lastAngle.ToString();//实际角度
                            }
                            #endregion

                            //更新页面信息
                            this.Invoke(new MethodInvoker(() =>
                            {
                                nCanFuGao = 2;//已返回电批结果 停止统计Z
                                bCanReSongLuoSi = btReSongDing.Visible = false;
                                //lbNiuLi.Text = fTargetTorque + "/" + productTaskRecord.TaskPamaReal1;//实际扭力
                                //lbAngle.Text = fTargetAngle + "/" + productTaskRecord.TaskPamaReal2;//实际角度
                                ////lbSpeed.Text = fSpeed + "/" + Math.Round((dLuoSiFinishZ - listdPositionNeed[2]) * dAccuracyZ, 2) + "mm";//浮高

                                DataRow row = dtLuoSiRecordList.NewRow();
                                row["RowNo"] = productTaskRecord.WorkNo;
                                row["Torque"] = productTaskRecord.TaskPamaReal1;//实际扭力
                                row["Angle"] = productTaskRecord.TaskPamaReal2;//实际角度
                                row["Result"] = (productTaskRecord.TightenPrepare == 0 ? "" : "预拧 ") + (nReturnState == 1 ? "OK" : "NG");
                                dtLuoSiRecordList.Rows.Add(row);
                                dgvList.DataSource = null;
                                if (dtLuoSiRecordList.Rows.Count > 0)
                                {
                                    dgvList.DataSource = dtLuoSiRecordList;
                                }
                            }));
                            UnifiedObj.WriteLog(1, "3.6:" + (nReturnState == 1 ? "OK" : "NG") +
                                " 扭力:" + productTaskRecord.TaskPamaReal1 + " 角度:" + productTaskRecord.TaskPamaReal2);
                        }
                        else//无电批调试 停2秒 返回模拟NG
                        {
                            Thread.Sleep(2000);
                            nReturnState = 1;
                            UpdateTip("");
                            bCanReSongLuoSi = false;
                            this.Invoke(new MethodInvoker(() =>
                            {
                                btReSongDing.Visible = false;
                                DataRow row = dtLuoSiRecordList.NewRow();
                                row["RowNo"] = productTaskRecord.WorkNo;
                                row["Torque"] = "test1";//实际扭力
                                row["Angle"] = "test2";//实际角度
                                row["Result"] = (productTaskRecord.TightenPrepare == 0 ? "" : "预拧 ") + (nReturnState == 1 ? "OK" : "NG");
                                dtLuoSiRecordList.Rows.Add(row);
                                dgvList.DataSource = null;
                                if (dtLuoSiRecordList.Rows.Count > 0)
                                {
                                    dgvList.DataSource = dtLuoSiRecordList;
                                }
                            }));
                        }

                        if (nReturnState > 0)
                        {
                            productTaskRecord.State = nReturnState;//执行结果 0已送钉未执行 1 Pass 2 NG 3执行中
                            productTaskRecord.GongHao = strGongHao;
                            productTaskRecord.UserName = strUserName;
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }
                            if (bIsWorkModel)//工作模式才计产量
                            {
                                nReturn = ProductTaskRecordDbHelper.ProductTaskRecordUpdate(productTaskRecord);
                                if (nReturn < 1)
                                {
                                    UpdateTip("Error:行1700 ProductTaskRecordUpdate 更新产品任务记录异常。");
                                    PlaySound("更新产品任务记录异常。");
                                    bIsWorking = false;
                                    return;
                                }
                            }

                            productRecord.GongHao = strGongHao;
                            productRecord.UserName = strUserName;

                            if (nReturnState == 1)//Pass
                            {
                                if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                                { 
                                    UnifiedObj.SetLed(true, 2);//绿灯
                                }
                                this.Invoke(new MethodInvoker(() =>
                                {
                                    UpdateWorkStateShow(2);//通过
                                    //更新主表记录状态
                                    if (bIsWorkModel)//工作模式才计产量
                                    {
                                        nToDayLuoSitNum += 1;
                                        this.Invoke(new MethodInvoker(() =>
                                        {
                                            lbLuoSiNum.Text = nToDayLuoSitNum.ToString();
                                        }));
                                    }
                                    //打螺丝PASS 
                                    if (listTaskModel[i - 1].TightenPrepare == 0)
                                    {
                                        productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass);
                                    }
                                    else
                                    {
                                        productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass, 0);
                                    }
                                    //productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass);
                                }));
                                UpdateTip("第 " + i + " 个螺丝返回PASS.");
                                PlaySound("打螺丝合格。");

                                //更新当前螺丝任务状态 
                                if (i < listTaskModel.Count)//非最后一个螺丝 将打下一个
                                {
                                    productRecord.WorkNo = i + 1;//接着打下一个螺丝
                                    productRecord.TaskStepNo = nTaskStepNo = 0; //新螺丝步骤从头开始
                                    if (listTaskModel[i].ScrewModel > 0)//下个步骤是否需要要打螺丝
                                    {
                                        productRecord.TaskStepScrewNum = 1;//需送一个钉
                                    }
                                    else
                                    {
                                        productRecord.TaskStepScrewNum = 0;//无需送螺丝
                                    }
                                }
                                else
                                {
                                    productRecord.TaskStepNo = nTaskStepNo = 5; //到二次扫码步骤
                                }

                                if (bIsWorkModel)//工作模式才计产量
                                {
                                    nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                                    if (nReturn < 1)
                                    {
                                        UpdateTip("Error:行1230 ProductRecordUpdate 作业第4步 电批返回PASS 更新产品记录异常。");
                                        PlaySound("电批返回合格|更新产品记录异常。");
                                        bIsWorking = false;
                                        return;
                                    }
                                }
                                Thread.Sleep(500);
                                nCanFuGao = 0;
                                dLuoSiFinishZ = 0;
                                UnifiedObj.WriteLog(1, "3.7.1:OK 3阶段完成\r\n");
                                if (i == listTaskModel.Count)//打完螺丝 跳二次扫码
                                {
                                    goto case 5;
                                }
                                break;
                            }
                            else//电批打螺丝NG 弹品质页面
                            {
                                this.Invoke(new MethodInvoker(() =>
                                {
                                    //打螺丝NG
                                    UpdateWorkStateShow(3);//NG

                                    if (listTaskModel[i - 1].TightenPrepare == 0)
                                    {
                                        productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.NG);
                                    }
                                    else
                                    {
                                        productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.NG, 0);
                                    }
                                    //productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.NG);
                                }));
                                UpdateTip("第 " + i + " 个螺丝返回NG.");
                                PlaySound("打螺丝不合格。");

                                //更新当前螺丝任务状态 
                                productRecord.TaskStepNo = nTaskStepNo = 4; //NG弹品质异常判定页面

                                if (bIsWorkModel)//工作模式才计产量
                                {
                                    if (bNGIsFinisth)//NG直接结束
                                    {
                                        productRecord.State = 3;
                                    }
                                    nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                                    if (nReturn < 1)
                                    {
                                        UpdateTip("Error:行1260 ProductRecordUpdate 电批返回NG 更新产品记录异常。");
                                        PlaySound("电批返回不合格|更新产品记录异常。");
                                        bIsWorking = false;
                                        return;
                                    }
                                }
                                Thread.Sleep(200);

                                if (bNGIsFinisth)//NG直接结束
                                {
                                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                                    {
                                        bProudctNG = true;
                                        UnifiedObj.SetLed(true, 3);//蜂鸣
                                        Thread.Sleep(20);
                                        UnifiedObj.SetLed(true, 0);//亮红灯
                                        Thread.Sleep(20);
                                        UnifiedObj.SetLed(false, 2);//灭绿灯
                                    }
                                    UnifiedObj.WriteLog(1, "3.7.2:NG结束 3阶段完成\r\n");
                                    break;
                                }
                                else//NG需工艺品质二次判定
                                {
                                    UnifiedObj.WriteLog(1, "3.7.3:NG需工艺品质二次判定 3阶段完成\r\n");
                                    goto case 4;
                                }
                            }
                        }
                        else//未获取到电批返回结果 
                        {
                            Thread.Sleep(20);
                        }
                        break;
                        //PASS 打下个螺丝 NG跳case 4
                        #endregion

                    case 4:
                        #region NG弹品质异常处理 更新任务记录
                        if (!btStopWork.Visible)//停止按钮点了后 不可见
                        {
                            return;
                        }
                        if (lbResult.Text != "NG")
                        {
                            this.Invoke(new MethodInvoker(() =>
                            {
                                UpdateWorkStateShow(3);//NG
                            }));
                        }
                        UpdateTip("请判定当前异常原因。");
                        PlaySound("请判定当前异常原因");
                        if (bIsWorkModel && nProductTaskRecordID < 1)//异常等接着上次执行 没经过case 0 productTaskRecord 实体为空
                        {
                            productTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecord(productRecord.ProductRecordID,
                                listTaskModel[i - 1].Id, i, 2);
                            if (productTaskRecord == null)
                            {
                                UpdateTip("Error:行1310 GetProductTaskRecord 未查询到产品作业记录。");
                                PlaySound("未查询到产品作业记录。");
                                bIsWorking = false;
                                return;
                            }
                            else
                            {
                                nProductTaskRecordID = productTaskRecord.ProductTaskRecordID;
                            }
                        }
                        this.Invoke(new MethodInvoker(() =>
                        {
                            bCanReSongLuoSi = btReSongDing.Visible = false;
                            if (formNGJudgment.Visible == false)
                            {
                                formNGJudgment.nReDoSongDing = -1;
                                formNGJudgment.bIsWorkModel = bIsWorkModel;
                                formNGJudgment.productTaskRecordNG = productTaskRecord;
                                formNGJudgment.ShowDialog();
                            }
                        }));
                        UnifiedObj.WriteLog(1, "4.1:待品质判定异常结果");

                        //等品质判定异常结果
                        while (true)
                        {
                            if (!btStopWork.Visible)//停止按钮点了后 不可见
                            {
                                bIsWorking = false;
                                return;
                            }
                            if (formNGJudgment.nCheckState > 0)
                            {
                                break;
                            }
                            Thread.Sleep(100);
                        }
                        //4品质判定PASS 5品质判定NG 6品质判定重做
                        if (formNGJudgment.nCheckState == 4)//品质判定pass 
                        {
                            if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                            {
                                    UnifiedObj.SetLed(false, 0);//红灯
                                    Thread.Sleep(20);
                                    UnifiedObj.SetLed(true, 2);//绿灯
                                    Thread.Sleep(20);
                            }
                            this.Invoke(new MethodInvoker(() =>
                            {
                                UpdateWorkStateShow(2);//通过
                                UpdateTip("");
                                //更新主表记录状态
                                if (bIsWorkModel)//工作模式才计产量
                                {
                                    nToDayLuoSitNum += 1;
                                    this.Invoke(new MethodInvoker(() =>
                                    {
                                        lbLuoSiNum.Text = nToDayLuoSitNum.ToString();
                                    }));
                                }
                            }));
                            while (true)
                            {
                                for (int m = 0; m < 10; m++)
                                {
                                    Thread.Sleep(50);
                                }
                                break;
                            }
                            if (i < listTaskModel.Count)
                            {
                                productRecord.WorkNo = i + 1;//接着打下一个螺丝
                                if (listTaskModel[i].ScrewModel > 0)//下个步骤是否需要要打螺丝
                                {
                                    productRecord.TaskStepScrewNum = 1;//需送一个钉
                                }
                                else
                                {
                                    productRecord.TaskStepScrewNum = 0;//无需送螺丝
                                }
                            }
                            productRecord.TaskStepNo = nTaskStepNo = 0; //新螺丝步骤从头开始
                            if (listTaskModel[i - 1].TightenPrepare == 0)
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass);
                            }
                            else
                            {
                                productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass, 0);
                            }
                            //productImgControl1.SetTaskStatus(nGongXuNo, i, TestStatus.Pass);
                            UnifiedObj.WriteLog(1, "4.2.1:品质判定OK");
                        }
                        else
                        {
                            //ng 重打并需要重新送钉 原来螺丝报废 不送钉 原螺丝认为可继续用不算报废 更新页面对应螺钉仓 废螺丝数量
                            if (formNGJudgment.nCheckState == 5 || formNGJudgment.nReDoSongDing == 1)
                            {
                                this.Invoke(new MethodInvoker(() =>
                                {
                                    if (listTaskModel[i - 1].ScrewModel == 1)
                                    {
                                        listScrewModel[0].CapacityNGNum += 1;
                                        lbLuoSiBaoFei1.Text = "报废 " + listScrewModel[0].CapacityNGNum;
                                    }
                                    else
                                    {
                                        listScrewModel[1].CapacityNGNum += 1;
                                        lbLuoSiBaoFei2.Text = "报废 " + listScrewModel[1].CapacityNGNum;
                                    }
                                    listScrewModel[2].CapacityNGNum += 1;
                                    lbLuoSiBaoFei3.Text = "NG " + listScrewModel[2].CapacityNGNum;

                                    //NG螺钉应丢进废螺丝仓数量+1
                                    nReturn = ScrewDbHelper.ScrewModelNGNumAdd(Convert.ToInt32(listTaskModel[i - 1].ScrewModel));
                                    if (nReturn < 1)
                                    {
                                        UpdateTip("Error:行1410 ScrewModelNGNumAddNG 螺丝应丢进废螺丝仓，数量更新异常。");
                                        PlaySound("螺丝应丢进废螺丝仓，数量更新异常");
                                        bIsWorking = false;
                                        return;
                                    }
                                }));
                            }

                            if (formNGJudgment.nCheckState == 5)//品质判定ng 终止此产品作业
                            {
                                if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                                {
                                    bProudctNG = true;
                                    UnifiedObj.SetLed(true, 3);//蜂鸣
                                    Thread.Sleep(20);
                                    UnifiedObj.SetLed(true, 0);//亮红灯
                                    Thread.Sleep(20);
                                    UnifiedObj.SetLed(false, 2);//灭绿灯
                                }
                                productRecord.State = 3;
                                productRecord.TaskStepScrewNum = 0;
                                UnifiedObj.WriteLog(1, "4.2.2:品质判定NG");
                            }
                            else//重新打螺丝 当前螺丝任务标记重做 新增新螺丝记录
                            {
                                i -= 1;//重新打螺丝
                                if (formNGJudgment.nReDoSongDing == 1)
                                {
                                    productRecord.TaskStepNo = nTaskStepNo = 0; //步骤从头开始
                                    if (listTaskModel[i].ScrewModel > 0)//重打 当前步骤是否需要要打螺丝
                                    {
                                        productRecord.TaskStepScrewNum = 1;//需送一个钉
                                        UnifiedObj.WriteLog(1, "4.2.3:品质判定送钉重打");
                                    }
                                    else
                                    {
                                        productRecord.TaskStepScrewNum = 0;//无需送螺丝
                                        UnifiedObj.WriteLog(1, "4.2.4:品质判定不送钉重打");
                                    }
                                }
                                else
                                {
                                    productRecord.TaskStepScrewNum = 0;
                                    productRecord.TaskStepNo = nTaskStepNo = 1; //不重新打螺丝
                                    UnifiedObj.WriteLog(1, "4.2.5:品质判定不送钉");
                                }
                            }
                        }
                        nCanFuGao = 0;
                        dLuoSiFinishZ = 0;
                        //更新主表记录状态  
                        productRecord.GongHao = strGongHao;
                        productRecord.UserName = strUserName;
                        if (bIsWorkModel)//工作模式才计产量
                        {
                            nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);
                            if (nReturn < 1)
                            {
                                UpdateTip("Error:行1460 ProductRecordUpdate 更新产品NG记录，更新异常。");
                                PlaySound("更新产品不合格记录，更新异常");
                                bIsWorking = false;
                                return;
                            }
                        }
                        UnifiedObj.WriteLog(1, "4.3:品质判定结束 4阶段完成\r\n");
                        break;
                        #endregion

                    case 5:
                        UpdateTip("作业完成，请再次扫产品条码。");
                        PlaySound("作业完成，请再次扫产品条码");
                        UnifiedObj.WriteLog(1, "5.1:待二次扫码");
                        this.Invoke(new MethodInvoker(() =>
                        {
                            tbSN.Visible = false;
                            tbSN2.Visible = true;
                            tbSN2.Focus();
                        }));
                        
                        nHaveScan2 = 0;
                        while (true)//监控二次扫码完成
                        {
                            if (nHaveScan2 > 0)
                            {
                                break;
                            }
                            Thread.Sleep(50);
                        }
                        UnifiedObj.WriteLog(1, "5.2:二次扫码结束 4阶段完成"+(nHaveScan2 == 2 ? "\r\n" : ""));
                        break;
                }

                List<string> listNiuLi = new List<string>();
                List<string> listAngle = new List<string>();
                List<bool> listOKorNG = new List<bool>();

                if (nHaveScan2 > 1)//二次扫码 扫不同码 都NG结束
                {
                    nHaveScan2 = 0;
                    return;
                }

                if (productRecord.State == 3)//产品最终判定NG 作业完成
                {
                    UpdateTip("<"+ SN1 + ">不合格，请送维修。");
                    PlaySound("当前产品不合格，请送维修。");

                    if (Liju.Common.MES.IsUseMES)//打螺丝数据写MES
                    {
                        string strNGInfo = "";
                        listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(strSN);
                        for (int j = 0; j < listProductTaskRecord.Count; j++)
                        {
                            listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                            listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                            listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                            if (listProductTaskRecord[j].TaskPamaReal1.Trim() == "位置超限")
                            {
                                strNGInfo += "第" + (j + 1) + "个螺丝，电批作业中移出坐标范围，停止作业，判定NG";
                            }
                            else
                            {
                                strNGInfo += "第" + (j + 1) + "个螺丝，扭矩" + listProductTaskRecord[j].TaskPamaReal1 + ",角度" + listProductTaskRecord[j].TaskPamaReal2 +
                                    ",判定" + (listProductTaskRecord[j].State == 1 ? "OK;" : "NG;");
                            }
                        }
                        Liju.Common.MES.WorkStationNG(strSN, strGongXuName, Liju.Common.MES.WorkStation, 
                            "产品NG原因：某些螺丝判定为NG,具体如下：" + strNGInfo, listNiuLi, listAngle, listOKorNG, false);
                    }
                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                    {
                        Thread.Sleep(300);
                        UnifiedObj.SetLed(false, 3);//关蜂鸣
                    }

                    bIsWorking = false;
                    this.Invoke(new MethodInvoker(() =>
                    {
                        btStopWork.Visible = false;
                        tbSN.Text = SN1 = "";
                        tbSN.Focus();
                    }));
                    UnifiedObj.WriteLog(1, strSN + " 最终判定NG 作业完成\r\n");
                    return;
                }
                //打完所有螺丝后 更新主表状态
                if (i == listTaskModel.Count)
                {
                    bIsWorking = false;
                    this.Invoke(new MethodInvoker(() =>
                    {
                        tbSN.Text = tbSN2.Text = SN1 = "";
                        tbSN.Visible = true;
                        tbSN.Focus();
                        btStopWork.Visible = false;
                    }));
                    productRecord.State = 1;
                    productRecord.TaskStepScrewNum = 0;
                    if (bIsWorkModel)//工作模式才计产量
                    {
                        nReturn = ProductRecordDbHelper.ProductRecordUpdate(productRecord);

                        if (nReturn < 1)
                        {
                            UpdateTip("Error:行1510 ProductRecordUpdate 打完所有螺丝后，更新产品PASS记录，更新异常。");
                            PlaySound("打完所有螺丝后，更新产品合格记录，更新异常");
                            return;
                        }
                        else
                        {
                            nToDayProductNum += 1;
                            this.Invoke(new MethodInvoker(() =>
                            {
                                lbProductNum.Text = nToDayProductNum.ToString();
                            }));
                        }
                    }

                    if (Liju.Common.MES.IsUseMES)//打螺丝数据写MES
                    {
                        listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(strSN);
                        for (int j = 0; j < listProductTaskRecord.Count; j++)
                        {
                            if (listProductTaskRecord[j].TightenPrepare == 0 )//非预拧才上传MES
                            {
                                listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                            }
                        }
                        Liju.Common.MES.WorkStationPass(strSN, listNiuLi, listAngle, listOKorNG, true);
                    }
                    SN1 = string.Empty;
                    UpdateTip("<" + strSN + ">作业完成。");
                    PlaySound("当前产品作业完成");
                    UnifiedObj.WriteLog(1, strSN + " 产品作业完成\r\n");
                    this.Invoke(new MethodInvoker(() =>
                    {
                        btDianJian.Visible = btTaoTongGuiWei.Visible = true;
                        btDianJian.Text = "开始点检";
                        tbSN.Focus();
                    }));
                }
            }
        }


        /// <summary>
        /// 获取设备连接状态 0力臂 1电批 2套筒 3上料机
        /// </summary>
        /// <returns></returns>
        private bool GetDeviceState()
        {

            return true;
        }

        /// <summary>
        /// 保存曲线扭矩和角度数据
        /// </summary>
        /// <param name="torques"></param>
        /// <param name="angles"></param>
        private void SaveCurveData(List<double> torques, List<double> angles, double spendTime)
        {
            try
            {
                string torqueStr = String.Join(",", torques);
                string angleStr = String.Join(",", angles);
                CurveModel curveModel = new CurveModel()
                {
                    TaskId = CurrentTaskId,
                    Torques = torqueStr,
                    Angles = angleStr,
                    TimeSpan = spendTime
                };
                bool result = CurveDbHelper.AddCurve(curveModel);
            }
            catch (Exception ex)
            {

                Debug.WriteLine($"SaveCurveData->{ex.Message}");
            }

        }

        private DDKCurveModel ddkCurveModel = new DDKCurveModel();
        /// <summary>
        /// 添加DDK波形数据
        /// curveType:波形类型 0:扭矩+角度 1:时间+扭矩
        /// </summary>
        /// <param name="baseStep"></param>
        /// <param name="values"></param>
        private void AddDDKScrewCurve(int curveType, double baseStep, List<double> values)
        {
            try
            {
                string torqueStr = String.Join(",", values);
                if (curveType == 0)
                {
                    ddkCurveModel.TaskId = CurrentTaskId;
                    ddkCurveModel.AngleTorques = torqueStr;
                    ddkCurveModel.AngleStep = baseStep;
                }
                else if (curveType == 1)
                {
                    ddkCurveModel.TimeTorques = torqueStr;
                    ddkCurveModel.TimeStep = baseStep;
                }
                if (ddkCurveModel.AngleStep > 0 && ddkCurveModel.TimeStep > 0)
                {
                    bool result = CurveDbHelper.AddDDKCurve(ddkCurveModel);
                    ddkCurveModel.AngleStep = 0;
                    ddkCurveModel.TimeStep = 0;
                }
            }
            catch (Exception ex)
            {

                Debug.WriteLine($"SaveCurveData->{ex.Message}");
            }
        }

        /// <summary>
        /// 返回拧紧结果
        /// </summary>
        /// <param name="result">
        /// ruslt  0:REJECT(NG) 1:ACCEPT(OK) 2:ABNORMAL(系统报警) 3:STOP(紧急停止) 4:BYPASS(信号中断) 
        /// </param>
        /// <param name="lastTorque"></param>
        /// <param name="lastAngle"></param>
        private void LoadScrewResult(int result, double lastTorque, double lastAngle)
        {

        }

        /// <summary>
        /// 切换工作模式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btWork_Click(object sender, EventArgs e)
        {
            //需完成当前产品才能切换工作模式
            if (!bIsWorking)
            {
                if ((bIsWorkModel && ((Button)sender).Text == "工作模式") ||
                    (!bIsWorkModel && ((Button)sender).Text == "测试模式"))
                {
                    return;
                }
                if (bIsWorkModel)//工作模式切换为测试模式
                {
                    bIsWorkModel = false;
                    btWork.BackgroundImage = LiJu.Properties.Resources.gognzuo;
                    btWorkTest.BackgroundImage = LiJu.Properties.Resources.ceshi2;
                    MessageBox.Show("测试模式，将不计产品的产量。");
                }
                else
                {
                    bIsWorkModel = true;
                    btWork.BackgroundImage = LiJu.Properties.Resources.gongzuo2;
                    btWorkTest.BackgroundImage = LiJu.Properties.Resources.ceshi;
                }
            }
            else
            {
                MessageBox.Show("作业中，请先完成当前产品，再切换工作模式。");
                this.ActiveControl = null;//去掉当前控件焦点
            }
        }

        /// <summary>
        /// 获取当前位移编码器位置
        /// </summary>
        /// <returns></returns>
        private void GetPositionNow()
        {
            //获取当前电批位置 更新页面坐标
            if (UnifiedObj.DeviceConState[0] == 1)
            {
                //读取编码器值
                UnifiedObj.GetPosition();

                if (UnifiedObj.arrayPosition[0] < 1 || UnifiedObj.arrayPosition[1] < 1 ||
                    UnifiedObj.arrayPosition[2] < 1 || UnifiedObj.arrayPosition[3] < 1)
                {
                    MessageBox.Show("编码器通信异常，请重新打开程序。");
                    // 终止整个应用程序的运行
                    Environment.Exit(Environment.ExitCode);
                    return;
                }

                //可计算浮高时 统计编码器Z最大值
                if (nCanFuGao == 1 && dLuoSiFinishZ > UnifiedObj.arrayPosition[2])
                {
                    dLuoSiFinishZ = UnifiedObj.arrayPosition[2];
                }

                if (bIsShowPostion)
                {
                    this.BeginInvoke((Action)delegate ()
                    {
                        lbPositionNow.Text = "电批当前位置：" + UnifiedObj.arrayPosition[0] + ", " + UnifiedObj.arrayPosition[1] + ", " +
                            UnifiedObj.arrayPosition[2] + ", " + UnifiedObj.arrayPosition[3];
                    });
                }
            }
            timerPositionMonitor.Start();
        }

        //位移编码器监控程序
        public void timerPositionMonitor_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            timerPositionMonitor.Stop();

            //须从UI线程另启动一个线程,在新线程调用异步刷新提示信息
            threadPositionMonitor = new Thread(new ThreadStart(GetPositionNow));
            threadPositionMonitor.IsBackground = true;
            threadPositionMonitor.Start();
        }

        //IO控制器监控
        public void timerIOMonitor_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            timerIOMonitor.Stop();

            //须从UI线程另启动一个线程,在新线程调用异步刷新提示信息
            threadIOMonitor = new Thread(new ThreadStart(IOMonitor));
            threadIOMonitor.IsBackground = true;
            threadIOMonitor.Start();
        }

        /// <summary>
        /// 上一个废螺丝感应IO值 0初始化 1是 2否
        /// </summary>
        int nIsFeiLuoSiRre = 0;

        /// <summary>
        /// 螺丝机1 上一个缺料满料状态 IO值 0正常 1缺料 2满料
        /// </summary>
        int nLuoSiJiStatePre1 = 0;

        /// <summary>
        /// 螺丝机2 上一个缺料满料状态 IO值 0正常 1缺料 2满料
        /// </summary>
        int nLuoSiJiStatePre2 = 0;

        /// <summary>
        /// IO控制器监控 丢废螺丝监控
        /// </summary>
        private void IOMonitor()
        {
            if (UnifiedObj.DeviceConState[2] == 0)
            {
                return;
            }
            //IO控制器16IN值
            arrayInValue = UnifiedObj.GetInAllValue();
            if (UnifiedObj.GetStopDown() )//按下急停按钮
            {
                UnifiedObj.SetDianPiCanWork(false);
                UnifiedObj.SetLed(true, 3);//蜂鸣
            }
            else if(!UnifiedObj.GetStopDown() && bProudctNG == false)
            {
                UnifiedObj.SetLed(false, 3);//蜂鸣
            }
            //if (UnifiedObj.GetStopDown() || UnifiedObj.DianPiCanWork == false)//按下急停按钮 电批急停
            //{
            //    UnifiedObj.SetDianPiCanWork(false);
            //    UnifiedObj.SetLed(true, 3);//蜂鸣
            //}
            //else
            //{
            //    UnifiedObj.SetDianPiCanWork(true);
            //    UnifiedObj.SetLed(false, 3);//蜂鸣
            //}

            //if (this.IsHandleCreated && !this.IsDisposed)
            //{
            //    this.Invoke(new MethodInvoker(() =>
            //    {
            //        if (UnifiedObj.GetLuoSiJiState(1) == 0 && nIsFeiLuoSiRre != 0)
            //        {
            //            nIsFeiLuoSiRre = 0;
            //            lbLuoSiJi1.Text = "螺丝机1";
            //            lbLuoSiJi1.ForeColor = Color.DeepSkyBlue;
            //        }
            //        else if (UnifiedObj.GetLuoSiJiState(1) == 1 && nIsFeiLuoSiRre != 1)
            //        {
            //            nIsFeiLuoSiRre = 1;
            //            lbLuoSiJi1.Text = "螺丝机1 缺料";
            //            lbLuoSiJi1.ForeColor = Color.Fuchsia;
            //        }
            //        else if (UnifiedObj.GetLuoSiJiState(1) == 2 && nIsFeiLuoSiRre != 2)
            //        {
            //            nIsFeiLuoSiRre = 2;
            //            lbLuoSiJi1.Text = "螺丝机1 满料";
            //            lbLuoSiJi1.ForeColor = Color.Fuchsia;
            //        }

            //        if (UnifiedObj.GetLuoSiJiState(2) == 0 && nIsFeiLuoSiRre != 0)
            //        {
            //            nIsFeiLuoSiRre = 0;
            //            lbLuoSiJi2.Text = "螺丝机2";
            //            lbLuoSiJi1.ForeColor = Color.DeepSkyBlue;
            //        }
            //        else if (UnifiedObj.GetLuoSiJiState(2) == 1 && nIsFeiLuoSiRre != 1)
            //        {
            //            nIsFeiLuoSiRre = 1;
            //            lbLuoSiJi2.Text = "螺丝机2 缺料";
            //            lbLuoSiJi1.ForeColor = Color.Fuchsia;
            //        }
            //        else if (UnifiedObj.GetLuoSiJiState(2) == 2 && nIsFeiLuoSiRre != 2)
            //        {
            //            nIsFeiLuoSiRre = 2;
            //            lbLuoSiJi2.Text = "螺丝机2 满料";
            //            lbLuoSiJi1.ForeColor = Color.Fuchsia;
            //        }
            //    }));
            //}
            if (!bIsWarning && (UnifiedObj.GetLuoSiJiWaring(1) || UnifiedObj.GetLuoSiJiWaring(2)))//螺丝机1 2报警 亮黄灯
            {
                bIsWarning = true;
                if (bLedEnable)
                {
                    UnifiedObj.SetLed(true, 1);
                }
            }
            else if (bIsWarning && !UnifiedObj.GetLuoSiJiWaring(1) && !UnifiedObj.GetLuoSiJiWaring(2))//没报警 灭黄灯
            {
                bIsWarning = false;
                if (bLedEnable)
                {
                    UnifiedObj.SetLed(false, 1);
                }
            }
            if (!isTaoTongTishi)//正常情况 非套筒提示状态 根据套筒到位情况 亮灯
            {
                for (int i = 1; i < 5; i++)
                {
                    //套筒到位状态变化
                    if (UnifiedObj.GetTaoTongState(i) && UnifiedObj.TaoTongLEDState[i - 1] != 1)//套筒在位
                    {
                        UnifiedObj.SetTaoTongGreen(true, i);// 亮套筒绿灯
                    }
                    else if (!UnifiedObj.GetTaoTongState(i) && UnifiedObj.TaoTongLEDState[i - 1] != 0)//套筒不在位
                    {
                        UnifiedObj.SetTaoTongRed(true, i);// 亮套筒红灯
                    }
                }
            }

            //废螺丝IO=0是感应到有料 且与上一个信号不一样有变化
            if (arrayInValue[8] && nIsFeiLuoSiRre != 1)
            {
                if (formSongDingJudge.nState == 1)//重新送钉判定要送
                {
                    formSongDingJudge.nState = 3;//感应到已丢废螺丝
                }
                //更新页面废螺钉库存
                this.Invoke(new MethodInvoker(() =>
                {
                    //NG螺钉实际丢进废弃螺钉仓数量+1
                    int nReturn = ScrewDbHelper.ScrewModelNGNumRealAdd();
                    if (nReturn < 1)
                    {
                        UpdateTip("Error:行1290 ScrewModelNGNumRealAdd NG螺丝实际丢进废螺丝仓数量，更新异常。");
                        PlaySound("不合格螺丝丢进废螺丝仓后，更新数量异常");
                        return;
                    }

                    listScrewModel[2].CapacityNow += 1;
                    lbLuoSiCang3.Text = listScrewModel[2].CapacityNow.ToString();

                    //库存报警
                    if (listScrewModel[2].CapacityNow >= arrayLuoSiWaringNum[2])
                    {
                        lbLuoSiCang3.ForeColor = Color.Gold;
                    }
                    else
                    {
                        lbLuoSiCang3.ForeColor = Color.White;
                    }
                }));
            }
            nIsFeiLuoSiRre = arrayInValue[8] ? 1 : 2;
            timerIOMonitor.Start();
        }

        /// <summary>
        /// 更新提示信息 1提示信息 2 3
        /// </summary>
        private void UpdateTip(string strMesage, int nType = 1)
        {
            if (this.IsHandleCreated)
            {
                this.Invoke(new MethodInvoker(() =>
                {
                    lbTip.Text = strMesage.Replace("|","");// |是用于语音分割 提示文字不需要
                }));
            }
        }

        /// <summary>
        /// 停止作业
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtStopWork_Click(object sender, EventArgs e)
        {
            if (btStopWork.Visible)
            {
                ScanCodeOld = "";
                bIsWorking = bProudctNG = false;
                this.Invoke(new MethodInvoker(() =>
                {
                    btStopWork.Visible = btReSongDing.Visible = false;
                    btDianJian.Visible = btTaoTongGuiWei.Visible = true;
                    tbSN.Text = tbSN2.Text = lbTip.Text = SN1 = "";
                    tbSN.Visible = true;
                    tbSN.Focus();
                    tbSN2.Visible = false;
                    //lbWorkNo.Text = lbNiuLi.Text = lbAngle.Text = lbSpeed.Text = lbTip.Text = "";
                    productImgControl1.ClearData();
                    UpdateWorkStateShow(0);//待扫码
                }));
                UpdateTip("");
                //电批吸附关
                if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                {
                    UnifiedObj.SetDianPiXiFu(false);
                    Thread.Sleep(20);
                }
                //电批急停
                UnifiedObj.DianPiCanWork = false;
                UnifiedObj.SetDianPiCanWork(false);
            }
        }

        /// <summary>
        /// 套筒卡子缩回 弹出逻辑状态 即发的是缩回/弹出指令
        /// </summary>
        bool[] bTaoTongKaState = { false, false, false, false };

        /// <summary>
        /// 检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
        /// </summary>
        /// <param name="oTaoTongNo"></param>
        private void CheckAddOperateTaoTong(int TaoTongNo)
        {
            isTaoTongCheckFinish = false;
            //判断套筒
            if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
            {
                //套筒归位监控 除指定套筒外 
                TaoTongGuiWei(TaoTongNo);

                //指定套筒推杆松开
                UnifiedObj.SetTaoTongOpen(true, TaoTongNo);
                Thread.Sleep(20);

                isTaoTongTishi = true;
                //套筒启用 未取走 才提示
                if (arrTaoTongEnable[TaoTongNo - 1] && UnifiedObj.GetTaoTongState(TaoTongNo))
                {
                    UpdateTip("请取 " + TaoTongNo + "号套筒");
                    PlaySound("请取|" + TaoTongNo + "号|套筒");

                    //监控取走指定套筒
                    while (true)
                    {
                        if (UnifiedObj.GetStopDown() || (DianJianState == 0 && !btStopWork.Visible)
                            || DianJianState == 2)//停止按钮点了后 不可见 急停
                        {
                            UpdateTip("");
                            return;
                        }
                        //套筒启用 
                        if (arrTaoTongEnable[TaoTongNo - 1])
                        {
                            //套筒在位 未取走
                            if (UnifiedObj.GetTaoTongState(TaoTongNo))
                            {
                                //要还的套筒 灭绿灯 闪灭效果
                                UnifiedObj.SetTaoTongGreen(false, TaoTongNo);
                                Thread.Sleep(150);

                                //要还的套筒 亮绿灯 闪灭效果
                                UnifiedObj.SetTaoTongGreen(true, TaoTongNo);
                                Thread.Sleep(150);
                            }
                            else//套筒已取走
                            {
                                //套筒已取走 亮红灯
                                UnifiedObj.SetTaoTongRed(true, TaoTongNo);
                                UpdateTip(TaoTongNo + "号套筒已取走。");
                                PlaySound(TaoTongNo + "号|套筒已取走");
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                        Thread.Sleep(100);
                    }
                }
                isTaoTongTishi = false;
                isTaoTongCheckFinish = true;
            }
            else//无IO控制器 
            {
                //提示取套筒
                UpdateTip("请取 " + TaoTongNo + "号套筒");
                PlaySound("请取|" + TaoTongNo + "号|套筒");
                Thread.Sleep(2000);
                UpdateTip(TaoTongNo + "号套筒已拿走。");
                PlaySound(TaoTongNo + "号|套筒已取走");
                isTaoTongCheckFinish = true;
                Thread.Sleep(2000);
            }
        }

        /// <summary>
        /// 下班后 套筒需全部归位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btTaoTongGuiWei_Click(object sender, EventArgs e)
        {
            if (bIsWorking)
            {
                UpdateTip("作业中，不能套筒归位。请作业完成后，再进行此操作。");
                PlaySound("作业中，不能套筒归位。请作业完成后，再进行此操作");
                return;
            }

            Task.Run(() =>
            {
                TaoTongGuiWei(0);//所有套筒要归位
            });

            ////测试 模拟打螺丝过程中 取2号套筒 其他套筒要归位
            //CheckAddOperateTaoTong(2);
        }

        /// <summary>
        /// 监控套筒归位操作 PaiChuTaoTongNo 不需要监控的套筒号 0全监控 >0指定套筒不监控
        /// </summary>
        /// <param name="PaiChuTaoTongNo"></param>
        private void TaoTongGuiWei(int PaiChuTaoTongNo)
        {
            UpdateTip("");

            //判断套筒
            if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
            {
                //提示需归还套筒
                string strTiShi = string.Empty;
                List<int> listNeedGuiHuanTaoTong = new List<int>();
                for (int i = 1; i < 5; i++)
                {
                    //套筒启用 且 套筒要在位 排除不监控的套筒
                    if (arrTaoTongEnable[i - 1] && !UnifiedObj.GetTaoTongState(i) && i != PaiChuTaoTongNo)
                    {
                        strTiShi += i + "号 ";
                        listNeedGuiHuanTaoTong.Add(i);
                        //要归还的套筒 要松开
                        UnifiedObj.SetTaoTongOpen(true, i);
                    }
                }

                isTaoTongTishi = true;
                //监控 要归还的套筒归位
                while (true)
                {
                    if (UnifiedObj.GetStopDown())//停止按钮点了后 不可见 急停
                    {
                        return;
                    }
                    strTiShi = string.Empty;
                    for (int i = 1; i < 5; i++)
                    {
                        //套筒启用 且 套筒要在位 排除不监控的套筒
                        if (arrTaoTongEnable[i - 1] && !UnifiedObj.GetTaoTongState(i) && i != PaiChuTaoTongNo)
                        {
                            strTiShi += i + "号| ";
                        }
                    }
                    if (!string.IsNullOrWhiteSpace(strTiShi))
                    {
                        UpdateTip("请将 " + strTiShi + "套筒归位。");
                        PlaySound("请将|" + strTiShi + "套筒归位");
                    }

                    int nNum = 0;
                    for (int i = 0; i < listNeedGuiHuanTaoTong.Count; i++)
                    {
                        //套筒启用 
                        if (arrTaoTongEnable[listNeedGuiHuanTaoTong[i] - 1])
                        {
                            //要还的套筒归还后 夹住
                            if (UnifiedObj.GetTaoTongState(listNeedGuiHuanTaoTong[i]))
                            {
                                nNum += 1;
                                //要还的套筒已到位 亮绿灯
                                UnifiedObj.SetTaoTongGreen(true, listNeedGuiHuanTaoTong[i]);
                                Thread.Sleep(20);
                                UnifiedObj.SetTaoTongOpen(false, listNeedGuiHuanTaoTong[i]);
                                Thread.Sleep(20);
                                //确认套筒在位 防止在夹的过程中 又拿走
                                if (UnifiedObj.GetTaoTongState(listNeedGuiHuanTaoTong[i]))
                                {
                                    listNeedGuiHuanTaoTong.RemoveAt(i);
                                }
                                else//不在位 松开
                                {
                                    UnifiedObj.SetTaoTongOpen(true, listNeedGuiHuanTaoTong[i]);
                                }
                            }
                            else
                            {
                                //要还的套筒 灭红灯 闪灭效果
                                UnifiedObj.SetTaoTongRed(false, listNeedGuiHuanTaoTong[i]);
                                Thread.Sleep(150);

                                //要还的套筒 亮红灯 闪灭效果
                                UnifiedObj.SetTaoTongRed(true, listNeedGuiHuanTaoTong[i]);
                                Thread.Sleep(150);
                            }
                        }
                    }
                    if (listNeedGuiHuanTaoTong.Count == 0)//剩余要还的套筒=0
                    {
                        UpdateTip("套筒已归位。");
                        PlaySound("套筒已归位");
                        break;
                    }
                    Thread.Sleep(200);
                }
                isTaoTongTishi = false;
            }
        }

        //点检
        private void BtDianJian_Click(object sender, EventArgs e)
        {
            if (bIsWorking)
            {
                UpdateTip("作业中，请先完成当前产品，或停止作业后，再点检。");
                PlaySound("作业中，请先完成当前产品，或停止作业后，再点检");
                return;
            }

            if (DianJianState == 0)
            {
                Task.Run(() =>
                {
                    DianJian();
                });
            }
            else
            {
                DianJianState = 2;
                if (UnifiedObj.DeviceConState[1] == 1)
                {
                    ////电批禁用使能
                    //LiJu.Common.Batch.DisEnable();

                    //电批急停
                    UnifiedObj.SetDianPiCanWork(false);
                }

                //设置取消点检状态后 留500ms结束其他监控线程
                DateTime dtFrom = DateTime.Now;
                while (true)
                {
                    if ((DateTime.Now - dtFrom).TotalMilliseconds > 500)
                    {
                        break;
                    }
                    Thread.Sleep(20);
                }
                //重置状态
                UpdateTip("");
                DianJianState = 0;
                formDianJian.nDianJianState = 0;
                formDianJian.nSleeveModelID = 0;
                formDianJian.nDianJianLuoSiPamar = 0;
                btDianJian.Text = "开始点检";
                tbSN.Focus();
            }
        }

        /// <summary>
        /// 点检流程
        /// </summary>
        private void DianJian()
        {
            DianJianState = 1;
            this.Invoke(new MethodInvoker(() =>
            {
                UpdateWorkStateShow(4);//点检
                btDianJian.Text = "点检结束";
                dtLuoSiRecordList.Clear();
                dgvList.DataSource = null;
                if (dtLuoSiRecordList.Rows.Count > 0)
                {
                    dgvList.DataSource = dtLuoSiRecordList;
                }
                formDianJian.ShowDialog();
            }));

            //等点检设置完成
            while (true)
            {
                if (formDianJian.nDianJianState > 0)
                {
                    if (formDianJian.nDianJianState == 1)
                    {
                        this.Invoke(new MethodInvoker(() =>
                        {
                            lbTaskNo.Text = "电批任务号: " + formDianJian.nDianJianLuoSiPamar;
                            lbTaoTongNo.Text = "套筒序号: " + formDianJian.nSleeveModelID;
                        }));
                    }
                    break;
                }
                Thread.Sleep(100);
            }
            //取消电检
            if (formDianJian.nDianJianState == 2)
            {
                //重置状态
                UpdateTip("");
                DianJianState = 0;
                UnifiedObj.DianPiCanWork = false;
                UnifiedObj.SetDianPiCanWork(true);
                formDianJian.nDianJianState = 0;
                formDianJian.nSleeveModelID = 0;
                formDianJian.nDianJianLuoSiPamar = 0;
                this.Invoke(new MethodInvoker(() =>
                {
                    btDianJian.Text = "开始点检";
                    tbSN.Focus();
                }));
                return;
            }
            //检测套筒状态 提示归还套筒 取指定套筒 套筒号从1开始
            CheckAddOperateTaoTong(formDianJian.nSleeveModelID);

            //等套筒检测完
            while (true)
            {
                //急停 点检结束 
                if (UnifiedObj.GetStopDown() || DianJianState == 2)
                {
                    return;
                }
                //套筒检测完 
                if (isTaoTongCheckFinish)
                {
                    break;
                }
                Thread.Sleep(50);
            }

            //发IO指令 禁用电批正反转按钮功能 马头用发TCP指令模式 无法在用IO模式实现
            if (UnifiedObj.DeviceConState[1] == 1 && DianJianState == 1)
            {
                ////电批移动到位 发电批参数指令                        
                //LiJu.Common.Batch.UseProgramIndex(formDianJian.nDianJianLuoSiPamar);
                ////发电批使能
                //LiJu.Common.Batch.Enable();

                //读取螺丝任务号参数 并显示到页面 目标扭力 目标角度 速度 
                GetLuoSiParamNiuLiAngleSpeed(formDianJian.nDianJianLuoSiPamar);

                int nReturnState = 0;//电批返回结果 0无 1Pass 2NG

                //取消电批急停
                UnifiedObj.DianPiCanWork = true;
                //重置电批结果
                UnifiedObj.DianPiOKNGClear();
                UnifiedObj.SetDianPiCanWork(true);
                Thread.Sleep(20);

                //设置电批任务号
                UnifiedObj.SetDDKTaskNo(formDianJian.nDianJianLuoSiPamar);
                Thread.Sleep(20);
                //电批吸附开
                if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                {
                    UnifiedObj.SetDianPiXiFu(true);
                    Thread.Sleep(20);
                }

                UpdateTip("请按电批启动键进行点检。");
                PlaySound("请按电批启动键进行点检");

                while (true)
                {
                    //急停 点检取消 
                    if (UnifiedObj.GetStopDown() || DianJianState == 2)
                    {
                        //电批急停
                        UnifiedObj.DianPiCanWork = false;
                        UnifiedObj.SetDianPiCanWork(false);
                        Thread.Sleep(20);
                        //电批吸附关
                        if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                        {
                            UnifiedObj.SetDianPiXiFu(false);
                        }
                        return;
                    }
                    //监控启动信号
                    if (UnifiedObj.GetDianPiStart())
                    {
                        UnifiedObj.SetDianPiZhengZhuan(true);
                        break;
                    }
                    Thread.Sleep(50);
                }
                UpdateTip("电批作业中...");
                PlaySound("电批作业中");

                //监控电批作业完成
                while (true)
                {
                    //急停 点检取消 
                    if (UnifiedObj.GetStopDown() || DianJianState == 2)
                    {
                        //电批急停
                        UnifiedObj.DianPiCanWork = false;
                        UnifiedObj.SetDianPiCanWork(false);
                        Thread.Sleep(20);
                        //电批吸附关
                        if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                        {
                            UnifiedObj.SetDianPiXiFu(false);
                        }
                        return;
                    }
                    if (UnifiedObj.GetDianPiOKNG())
                    {
                        break;
                    }
                    Thread.Sleep(50);
                }

                //电批吸附关
                if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                {
                    UnifiedObj.SetDianPiXiFu(false);
                    Thread.Sleep(20);
                }

                if (UnifiedObj.DeviceEnable[1])//有电批
                {
                    ScrewResult screwResult = new ScrewResult();
                    screwResult = DDKBatch.ReadScrewResult();
                    if (screwResult.result == 0)//NG
                    {
                        nReturnState = 2;
                    }
                    else if (screwResult.result == 1)//OK
                    {
                        nReturnState = 1;
                    }

                    //更新页面信息
                    this.BeginInvoke(new MethodInvoker(() =>
                    {
                        //lbNiuLi.Text = fTargetTorque + "/" + screwResult.lastTorque;//实际扭力
                        //lbAngle.Text = fTargetAngle + "/" + screwResult.lastAngle;//实际角度

                        DataRow row = dtLuoSiRecordList.NewRow();
                        row["RowNo"] = "1";
                        row["Torque"] = screwResult.lastTorque;//实际扭力
                        row["Angle"] = screwResult.lastAngle;//实际角度
                        row["Result"] = nReturnState == 1 ? "OK" : "NG";
                        dtLuoSiRecordList.Rows.Add(row);
                        dgvList.DataSource = null;
                        if (dtLuoSiRecordList.Rows.Count > 0)
                        {
                            dgvList.DataSource = dtLuoSiRecordList;
                        }
                    }));

                    //读曲线数据 角度+扭矩
                    DDKBatch.ReadCurve(0, 4);
                    Thread.Sleep(100);
                    //读曲线数据 时间+扭矩
                    DDKBatch.ReadCurve(2, 4);
                    Thread.Sleep(100);

                    //电批急停
                    UnifiedObj.DianPiCanWork = false;
                    UnifiedObj.SetDianPiCanWork(false);
                    Thread.Sleep(20);
                    //重置电批结果
                    UnifiedObj.DianPiOKNGClear();
                    Thread.Sleep(20);

                }
                else//无电批调试 停2秒 返回模拟NG
                {
                    nReturnState = 2;
                    UpdateTip("");
                }

                #region 点检 监控马头电批作业完成
                ////监控马头电批作业完成
                //while (!isDianJian)
                //{
                //    //if ((DateTime.Now - dtFrom).TotalSeconds > 60)
                //    //{
                //    //    //重置状态
                //    //    isDianJian = false;
                //    //    formDianJian.nDianJianState = 0;
                //    //    formDianJian.nSleeveModelID = 0;
                //    //    formDianJian.nDianJianLuoSiPamar = 0;
                //    //    btDianJian.Text = "开始点检";
                //    //    UpdateTip("1分钟内未点检，或未收到电批返回结果，若需要可重新点检。");
                //    //    break;
                //    //}
                //    if (bIsHaveDianPi)//有电批
                //    {
                //        if (LiJu.Common.Batch.tightenModels.Count > 0)//等待马头电批返回结果
                //        {
                //            if (LiJu.Common.Batch.tightenModels[0].TighteningStatus == "OK")
                //            {
                //                nReturnState = 1;
                //            }
                //            else
                //            {
                //                nReturnState = 2;
                //            }
                //            UpdateTip("");

                //            //更新页面信息
                //            this.Invoke(new MethodInvoker(() =>
                //            {
                //                lbNiuLi.Text = fTargetTorqueLength + "/" + LiJu.Common.Batch.tightenModels[0].Torque;//实际扭力
                //                lbAngle.Text = fTargetAngle + "/" + LiJu.Common.Batch.tightenModels[0].Angle;//实际角度
                //                LiJu.Common.Batch.tightenModels.Clear();
                //            }));
                //        }
                //    }
                //    else//无电批调试 停2秒 返回模拟NG
                //    {
                //        nReturnState = 2;
                //        UpdateTip("");
                //    }
                #endregion

                if (nReturnState > 0)
                {
                    if (nReturnState == 1)//Pass
                    {
                        this.BeginInvoke(new MethodInvoker(() =>
                        {
                            UpdateWorkStateShow(2);//通过
                        }));
                        UpdateTip("点检PASS.");
                        PlaySound("点检合格");
                    }
                    else//打螺丝NG
                    {
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            bProudctNG = true;
                            UnifiedObj.SetLed(true, 3);//蜂鸣
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(true, 0);//亮红灯
                            Thread.Sleep(20);
                            UnifiedObj.SetLed(false, 2);//灭绿灯
                        }
                        this.BeginInvoke(new MethodInvoker(() =>
                        {
                            //打螺丝NG
                            UpdateWorkStateShow(3);//NG
                        }));
                        if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                        {
                            Thread.Sleep(300);
                            UnifiedObj.SetLed(false, 3);//关蜂鸣
                        }
                        UpdateTip("点检NG.");
                        PlaySound("点检不合格");
                    }
                    if (UnifiedObj.DeviceConState[1] == 1)
                    {
                        ////电批禁用使能
                        //LiJu.Common.Batch.DisEnable();

                        //电批急停
                        UnifiedObj.SetDianPiCanWork(false);
                    }
                    //重置状态
                    DianJianState = 0;
                    formDianJian.nDianJianState = 0;
                    formDianJian.nSleeveModelID = 0;
                    formDianJian.nDianJianLuoSiPamar = 0;
                    this.BeginInvoke(new MethodInvoker(() =>
                    {
                        btDianJian.Text = "开始点检";
                        tbSN.Focus();
                    }));
                }
                else//未获取到电批返回结果 
                {
                    Thread.Sleep(100);
                }
            }
        }

        //重新送钉判定 丢废螺丝后 才送同型号螺丝 
        private void BtReSongDing_Click(object sender, EventArgs e)
        {
            if (btStopWork.Visible && bCanReSongLuoSi)//作业中 才能重新送钉
            {
                //弹框 重新送钉判定
                formSongDingJudge.songDingJudgeModel.ProductSN = productTaskRecord.ProductSN;
                formSongDingJudge.songDingJudgeModel.WorkNo = productTaskRecord.WorkNo;
                formSongDingJudge.songDingJudgeModel.TaskID = productTaskRecord.TaskID;

                this.Invoke(new MethodInvoker(() =>
                {
                    formSongDingJudge.ShowDialog();
                }));

                //等判定完成
                while (true)
                {
                    if (formSongDingJudge.nState == 2 || formSongDingJudge.nState == 6)//不送 或 取消
                    {
                        return;
                    }
                    if (formSongDingJudge.nState > 0)
                    {
                        break;
                    }
                    Thread.Sleep(200);
                }

                this.Invoke(new MethodInvoker(() =>
                {
                    UpdateTip("请将废螺丝丢进废螺丝仓。");
                    PlaySound("请将废螺丝丢进废螺丝仓");
                }));

                //感应到已丢废螺丝 在IO监控里判断
                while (true)
                {
                    if (formSongDingJudge.nState == 3)
                    {
                        break;
                    }
                    Thread.Sleep(200);
                }

                //发送同型号螺丝指令
                SongLuoSiSetOut(productTaskRecord.ScrewModel);

                UpdateTip(listScrewModel[productTaskRecord.ScrewModel - 1].Model + " 送钉中...");
                PlaySound("送丁中...");

                //监控实际送钉是否完成
                SongLuoSiReal(productTaskRecord.ScrewModel);

                //实际只有送钉成功 才会到此步 未送成功还在监控中
                Int64 nReturn = SongDingJudgeDbHelper.SongDingAgainUpdate(formSongDingJudge.songDingJudgeModel.LogID, 3);
                if (nReturn < 1)
                {
                    MessageBox.Show("Error:行93 SongDingAgainUpdate 重新送钉成功后更新数据库记录失败。");
                    return;
                }

                UpdateTip("请将电批移动到：" + String.Join(",", listdPositionNeed));
            }
            return;
        }

        /// <summary>
        /// 发送螺丝指令 螺丝机ID 从1开始
        /// </summary>
        /// <param name="nLuoSiJiID">螺丝机ID 从1开始</param>
        private bool SongLuoSiSetOut(int nLuoSiJiID)
        {
            bool bReturn = false;
            //送同型号螺丝指令
            if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
            {
                if (nLuoSiJiID == 1)//1号螺丝仓送钉
                {
                    bReturn = UnifiedObj.SetLuoSiJiSongDing(true, 1);
                }
                else//2号螺丝仓送钉
                {
                    bReturn = UnifiedObj.SetLuoSiJiSongDing(true, 2);
                }
                if (bReturn)
                {
                    UpdateTip(listScrewModel[nLuoSiJiID - 1].Model + "螺丝 送钉指令发送成功。");
                    PlaySound("送丁指令发送成功");
                }
                else
                {
                    UpdateTip(listScrewModel[nLuoSiJiID - 1].Model + "螺丝 送钉指令发送失败。");
                    PlaySound("送丁指令发送失败");
                }
            }
            else//无IO控制器 当发指令成功
            {
                return true;
            }
            return bReturn;
        }

        /// <summary>
        /// 重置送钉信号
        /// </summary>
        /// <param name="nLuoSiJiID"></param>
        /// <returns></returns>
        private bool SongLuoSiReset(int nLuoSiJiID)
        {
            bool bReturn = false;
            //送同型号螺丝指令
            if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
            {
                Thread.Sleep(100);
                if (nLuoSiJiID == 1)//1号螺丝仓送钉
                {
                    bReturn = UnifiedObj.SetLuoSiJiSongDing(false, 1);
                }
                else//2号螺丝仓送钉
                {
                    bReturn = UnifiedObj.SetLuoSiJiSongDing(false, 2);
                }
                if (bReturn)
                {
                    UnifiedObj.WriteLog(1, listScrewModel[nLuoSiJiID - 1].Model + "螺丝 重置送钉信号成功。");
                }
                else
                {
                    UnifiedObj.WriteLog(1, listScrewModel[nLuoSiJiID - 1].Model + "螺丝 重置送钉信号失败。");
                }
            }
            return bReturn;
        }

        /// <summary>
        /// 监控实际送钉是否完成 更新页面螺丝库存 螺丝机ID 从1开始
        /// </summary>
        /// <param name="nLuoSiJiID">螺丝机ID 从1开始</param>
        /// <returns></returns>
        private void SongLuoSiReal(int nLuoSiJiID)
        {
            //监控到实际送钉成功
            while (true)
            {
                if (!btStopWork.Visible)//停止按钮点了后 不可见
                {
                    bIsWorking = false;
                    return;
                }
                bool bHaveSongDingIO = false;//实际送钉感应状态
                //if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                //{
                //    bHaveSongDingIO = UnifiedObj.GetSongDingState(listScrewModel[nLuoSiJiID - 1].Id);
                //}
                //else//无IO控制器 模拟感应送钉成功
                {
                    bHaveSongDingIO = true;
                }

                if (bHaveSongDingIO)
                {
                    ////螺钉机送钉成功 剩余库存数量-1
                    //int nReturn = ScrewDbHelper.ScrewModelUsed(Convert.ToInt32(listScrewModel[nLuoSiJiID - 1].Id));
                    //if (nReturn < 1)
                    //{
                    //    UpdateTip("Error:行560 ScrewModelUsed 螺钉机送钉成功后扣库存 更新数据库异常。");
                    //    bIsWorking = false;
                    //    return;
                    //}

                    ////更新页面螺钉库存
                    //if (listScrewModel[nLuoSiJiID - 1].Id == 1)//当前螺丝用的1号仓螺丝
                    //{
                    //    listScrewModel[0].CapacityNow -= 1;
                        //this.Invoke(new MethodInvoker(() =>
                        //{
                            //lbLuoSiCang1.Text = "有" + listScrewModel[0].CapacityNow.ToString();
                            ////库存报警
                            //if (listScrewModel[0].CapacityNow <= arrayLuoSiWaringNum[0])
                            //{
                            //    lbLuoSiCang1.ForeColor = Color.Gold;
                            //}
                            //else
                            //{
                            //    lbLuoSiCang1.ForeColor = Color.White;
                            //}
                        //}));
                    //    if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                    //    {
                    //        UnifiedObj.SetLuoSiJiSongDing(false, 1);//关送钉1
                    //    }
                    //}
                    //else//当前螺丝用的2号仓螺丝
                    //{
                    //    listScrewModel[1].CapacityNow -= 1;
                    //    this.Invoke(new MethodInvoker(() =>
                    //    {
                    //        lbLuoSiCang2.Text = listScrewModel[1].CapacityNow.ToString();
                            ////库存报警
                            //if (listScrewModel[1].CapacityNow <= arrayLuoSiWaringNum[1])
                            //{
                            //    lbLuoSiCang2.ForeColor = Color.Gold;
                            //}
                            //else
                            //{
                            //    lbLuoSiCang2.ForeColor = Color.White;
                            //}
                    //    }));
                    //    if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                    //    {
                    //        UnifiedObj.SetLuoSiJiSongDing(false, 2);//关送钉2
                    //    }
                    //}
                    UpdateTip(listScrewModel[nLuoSiJiID - 1].Model + "送螺丝成功。");
                    UnifiedObj.WriteLog(1, "1:监控到实际送钉成功信号");
                    PlaySound("送螺丝成功");
                    break;
                }
                if (UnifiedObj.DeviceConState[2] == 1)//有IO控制器
                {
                    Thread.Sleep(10);
                }
                else//无IO控制器 
                {
                    MessageBox.Show(listScrewModel[nLuoSiJiID - 1].Model + "送螺丝成功。");
                    Thread.Sleep(2000);
                    PlaySound("送螺丝成功");
                    break;
                }
            }
        }

        /// <summary>
        /// 上次扫码内容 防止文本框多次扫码 追加扫码内容
        /// </summary>
        string ScanCodeOld = string.Empty;

        private void tbSN_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)//回车触发
            {
                string strScanNew = tbSN.Text.Trim("\r".ToCharArray()).Trim();//去掉回车符
                if (ScanCodeOld.Length < strScanNew.Length)
                {
                    //作业中 再次扫码 文本框中是ScanCodeOld + SN2 要过滤上次扫码内容
                    if (strScanNew.StartsWith(ScanCodeOld))
                    {
                        strScanNew = strScanNew.Substring(ScanCodeOld.Length, strScanNew.Length - ScanCodeOld.Length);
                        if (ScanCodeOld == strScanNew)
                        {
                            ScanCodeSame = true;
                        }
                        ScanCodeOld = strScanNew;
                        tbSN.Text = strScanNew;
                        //光标移到最后
                        tbSN.SelectionStart = tbSN.Text.Length;
                        tbSN.SelectionLength = 0;
                    }
                }

                Task.Run(() =>
                {
                    DoWork(strScanNew);
                });
            }
        }

        //作业OK最后 要二次扫码确认
        private void TbSN2_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)//回车触发
            {
                if (tbSN.Text.Trim() == tbSN2.Text.Trim())
                {
                    nHaveScan2 = 1;
                }
                else//两次扫码不同 2个都NG
                {
                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                    {
                        bProudctNG = true;
                        UnifiedObj.SetLed(true, 3);//蜂鸣
                        Thread.Sleep(20);
                        UnifiedObj.SetLed(true, 0);//亮红灯
                        Thread.Sleep(20);
                        UnifiedObj.SetLed(false, 2);//灭绿灯
                    }

                    string NGReMark = "再次验证产品条码失败，两次扫描条码不一致，过站条码为<" + SN1 + ">,第二次扫描条码< " + tbSN2.Text.Trim() + ">";
                    UnifiedObj.WriteLog(1, NGReMark);

                    ProductRecordModel product1 = ProductRecordDbHelper.GetProductRecordInfo(SN1);
                    if (product1 == null)
                    {
                        product1 = new ProductRecordModel();
                        product1.ProductSN = SN1;
                        product1.State = 3;
                        product1.NGReMark = NGReMark;
                        ProductRecordDbHelper.ProductRecordAdd(product1);
                    }
                    else
                    {
                        product1.State = 3;
                        product1.NGReMark = NGReMark;
                        ProductRecordDbHelper.ProductRecordUpdate(product1);
                    }

                    ProductRecordModel product2 = ProductRecordDbHelper.GetProductRecordInfo(tbSN2.Text.Trim());
                    if (product2 == null)
                    {
                        product2 = new ProductRecordModel();
                        product2.ProductSN = tbSN2.Text.Trim();
                        product2.State = 3;
                        product2.NGReMark = NGReMark;
                        ProductRecordDbHelper.ProductRecordAdd(product2);
                    }
                    else
                    {
                        product2.State = 3;
                        product2.NGReMark = NGReMark;
                        ProductRecordDbHelper.ProductRecordUpdate(product2);
                    }

                    if (Liju.Common.MES.IsUseMES)//打螺丝数据写MES
                    {
                        List<string> listNiuLi = new List<string>();
                        List<string> listAngle = new List<string>();
                        List<bool> listOKorNG = new List<bool>();
                        List<ProductTaskRecord> listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(SN1);
                        if (listProductTaskRecord != null && listProductTaskRecord.Count > 0)
                        {
                            for (int j = 0; j < listProductTaskRecord.Count; j++)
                            {
                                if (listProductTaskRecord[j].TightenPrepare == 0)//非预拧才上传MES
                                {
                                    listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                    listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                    listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                                }
                            }
                        }
                        Liju.Common.MES.WorkStationNG(SN1, strGongXuName, Liju.Common.MES.WorkStation,
                            "NG原因：" + NGReMark, listNiuLi, listAngle, listOKorNG, false);

                        listNiuLi.Clear();
                        listAngle.Clear();
                        listOKorNG.Clear();
                        listProductTaskRecord = ProductTaskRecordDbHelper.GetProductTaskRecordList(tbSN2.Text.Trim());
                        if (listProductTaskRecord != null && listProductTaskRecord.Count > 0)
                        {
                            for (int j = 0; j < listProductTaskRecord.Count; j++)
                            {
                                if (listProductTaskRecord[j].TightenPrepare == 0)//非预拧才上传MES
                                {
                                    listNiuLi.Add(listProductTaskRecord[j].TaskPamaReal1);
                                    listAngle.Add(listProductTaskRecord[j].TaskPamaReal2);
                                    listOKorNG.Add(listProductTaskRecord[j].State == 1 ? true : false);
                                }
                            }
                        }
                        Liju.Common.MES.WorkStationNG(tbSN2.Text.Trim(), strGongXuName, Liju.Common.MES.WorkStation,
                            "NG原因：" + NGReMark, listNiuLi, listAngle, listOKorNG, false);
                    }
                    if (UnifiedObj.DeviceConState[2] == 1 && bLedEnable)
                    {
                        Thread.Sleep(300);
                        UnifiedObj.SetLed(false, 3);//关蜂鸣
                    }
                    BtStopWork_Click(null, null);
                    UpdateTip(NGReMark);
                    nHaveScan2 = 2;

                    //PlaySound("两次扫码不同，请重新扫码");
                }
            }
        }

        //打开MES中心
        private void lbMES_Click(object sender, EventArgs e)
        {
            MESControl formMESControl = new MESControl();
            formMESControl.ShowDialog();
        }

        /// <summary>
        /// 更新作业结果显示 0待扫码 1作业中 2通过 3NG 4点检
        /// </summary>
        /// <param name="State"></param>
        private void UpdateWorkStateShow(int State)
        {
            switch (State) 
            {
                case 0://待扫码
                    lbResult.Text = "待扫码";
                    lbResult.ForeColor = Color.Chocolate;
                    lbResult.Image = LiJu.Properties.Resources.dowork;
                    break;
                case 1://作业中
                    lbResult.Text = "作业中";
                    lbResult.ForeColor = Color.White;
                    lbResult.Image = LiJu.Properties.Resources.dowork;
                    break;
                case 2://通过
                    lbResult.Text = "通过";
                    lbResult.ForeColor = Color.White;
                    lbResult.Image = LiJu.Properties.Resources.pass;
                    break;
                case 3://NG
                    lbResult.Text = "NG";
                    lbResult.ForeColor = Color.White;
                    lbResult.Image = LiJu.Properties.Resources.ng;
                    break;
                case 4://点检
                    lbResult.Text = "";
                    lbResult.ForeColor = Color.Chocolate;
                    lbResult.Image = LiJu.Properties.Resources.dowork;
                    break;
            }
        }

        //string[] arrFile = { "001.wav", "002.wav", "003.wav" };
        //System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(SoundPlayer));//创建了线程
        //t.Start(arrFile);//开启线程

        /// <summary>
        /// 播放WAV语音 引用COM组件:Microsoft speech object Library 
        /// </summary>
        /// <param name="str">语音内容文本 不同语音文件的语音内容内容以 | 分割</param>
        private void PlaySound(string str)
        {
            //string[] arrVoiceContent = str.Split('|');
            //System.Threading.Thread thread = new System.Threading.Thread(() =>
            //{
            //    for (int i = 0; i < arrVoiceContent.Length; i++)
            //    {
            //        for (int j = 0; j < dtSound.Rows.Count; j++)
            //        {
            //            //根据语音内容找语音文件名
            //            if (dtSound.Rows[j]["VoiceContent"].ToString().Trim() == arrVoiceContent[i].Trim())
            //            {
            //                string strFileName = System.IO.Directory.GetCurrentDirectory() + "\\WAV\\" + dtSound.Rows[j]["FileName"].ToString().Trim();
            //                if (!System.IO.File.Exists(strFileName))
            //                {
            //                    return;
            //                }
            //                SpeechLib.SpVoiceClass spVoice = new SpeechLib.SpVoiceClass();
            //                SpeechLib.SpFileStreamClass spFile = new SpeechLib.SpFileStreamClass();
            //                spFile.Open(strFileName, SpeechLib.SpeechStreamFileMode.SSFMOpenForRead, true);
            //                SpeechLib.ISpeechBaseStream iSpeech = spFile as SpeechLib.ISpeechBaseStream;
            //                spVoice.SpeakStream(iSpeech, SpeechLib.SpeechVoiceSpeakFlags.SVSFIsFilename);
            //                spFile.Close();
            //                break;
            //            }
            //        }
            //    }
            //});
            //thread.Start();
        }


        private void DgvList_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //DgvList刷新时 会异常
        }

        /// 更改打螺丝记录 OK NG单元格背景色
        private void DgvList_DataSourceChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < dgvList.Rows.Count; i++)
            {
                if (i == 0)
                {
                    dgvList.Rows[0].Selected = false;
                }
                if (dgvList.Rows[i].Cells["Result"].Value == null)
                {
                    return;
                }
                if (dgvList.Rows[i].Cells["Result"].Value.ToString().Contains("OK"))
                {
                    dgvList.Rows[i].Cells["Result"].Style.ForeColor = Color.Lime;
                }
                else if (dgvList.Rows[i].Cells["Result"].Value.ToString().Contains("NG"))
                {
                    dgvList.Rows[i].Cells["Result"].Style.ForeColor = Color.Fuchsia;
                    dgvList.Rows[i].Cells["Result"].Style.Font = new Font(dgvList.Font, FontStyle.Bold);
                }
                else
                {
                    dgvList.Rows[i].Cells["Result"].Style.ForeColor = Color.White;
                }
            }
        }
    }




}
